summaryrefslogtreecommitdiffstats
path: root/unix/tcl.m4
blob: 6844843ce84b7781ce8e058f8bedabc3d978798e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
#------------------------------------------------------------------------
# SC_PATH_TCLCONFIG --
#
#	Locate the tclConfig.sh file and perform a sanity check on
#	the Tcl compile flags
#
# Arguments:
#	none
#
# Results:
#
#	Adds the following arguments to configure:
#		--with-tcl=...
#
#	Defines the following vars:
#		TCL_BIN_DIR	Full path to the directory containing
#				the tclConfig.sh file
#------------------------------------------------------------------------

AC_DEFUN([SC_PATH_TCLCONFIG], [
    #
    # Ok, lets find the tcl configuration
    # First, look for one uninstalled.
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	AC_ARG_WITH(tcl,
	    AC_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    with_tclconfig=${withval})
	AC_MSG_CHECKING([for Tcl configuration])
	AC_CACHE_VAL(ac_cv_c_tclconfig,[

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case ${with_tclconfig} in
		    */tclConfig.sh )
			if test -f ${with_tclconfig}; then
			    AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
			    with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
			fi ;;
		esac
		if test -f "${with_tclconfig}/tclConfig.sh" ; then
		    ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
		else
		    AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
		fi
	    fi

	    # then check for a private Tcl installation
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in \
			../tcl \
			`ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
			../../tcl \
			`ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
			../../../tcl \
			`ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
		    if test -f "$i/unix/tclConfig.sh" ; then
			ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
			break
		    fi
		done
	    fi

	    # on Darwin, check in Framework installation locations
	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
			`ls -d /Library/Frameworks 2>/dev/null` \
			`ls -d /Network/Library/Frameworks 2>/dev/null` \
			`ls -d /System/Library/Frameworks 2>/dev/null` \
			; do
		    if test -f "$i/Tcl.framework/tclConfig.sh" ; then
			ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
			break
		    fi
		done
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig=`(cd $i; pwd)`
			break
		    fi
		done
	    fi

	    # check in a few other private locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in \
			${srcdir}/../tcl \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
		    if test -f "$i/unix/tclConfig.sh" ; then
		    ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
		    break
		fi
		done
	    fi
	])

	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    AC_MSG_WARN([Can't find Tcl configuration definitions])
	    exit 0
	else
	    no_tcl=
	    TCL_BIN_DIR=${ac_cv_c_tclconfig}
	    AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
	fi
    fi
])

#------------------------------------------------------------------------
# SC_PATH_TKCONFIG --
#
#	Locate the tkConfig.sh file
#
# Arguments:
#	none
#
# Results:
#
#	Adds the following arguments to configure:
#		--with-tk=...
#
#	Defines the following vars:
#		TK_BIN_DIR	Full path to the directory containing
#				the tkConfig.sh file
#------------------------------------------------------------------------

AC_DEFUN([SC_PATH_TKCONFIG], [
    #
    # Ok, lets find the tk configuration
    # First, look for one uninstalled.
    # the alternative search directory is invoked by --with-tk
    #

    if test x"${no_tk}" = x ; then
	# we reset no_tk in case something fails here
	no_tk=true
	AC_ARG_WITH(tk,
	    AC_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    with_tkconfig=${withval})
	AC_MSG_CHECKING([for Tk configuration])
	AC_CACHE_VAL(ac_cv_c_tkconfig,[

	    # First check to see if --with-tkconfig was specified.
	    if test x"${with_tkconfig}" != x ; then
		case ${with_tkconfig} in
		    */tkConfig.sh )
			if test -f ${with_tkconfig}; then
			    AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
			    with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'`
			fi ;;
		esac
		if test -f "${with_tkconfig}/tkConfig.sh" ; then
		    ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
		else
		    AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
		fi
	    fi

	    # then check for a private Tk library
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in \
			../tk \
			`ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
			../../tk \
			`ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
			../../../tk \
			`ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
		    if test -f "$i/unix/tkConfig.sh" ; then
			ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
			break
		    fi
		done
	    fi

	    # on Darwin, check in Framework installation locations
	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
			`ls -d /Library/Frameworks 2>/dev/null` \
			`ls -d /Network/Library/Frameworks 2>/dev/null` \
			`ls -d /System/Library/Frameworks 2>/dev/null` \
			; do
		    if test -f "$i/Tk.framework/tkConfig.sh" ; then
			ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)`
			break
		    fi
		done
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig=`(cd $i; pwd)`
			break
		    fi
		done
	    fi
	    # check in a few other private locations
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in \
			${srcdir}/../tk \
			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
		    if test -f "$i/unix/tkConfig.sh" ; then
			ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
			break
		    fi
		done
	    fi
	])

	if test x"${ac_cv_c_tkconfig}" = x ; then
	    TK_BIN_DIR="# no Tk configs found"
	    AC_MSG_WARN([Can't find Tk configuration definitions])
	    exit 0
	else
	    no_tk=
	    TK_BIN_DIR=${ac_cv_c_tkconfig}
	    AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
	fi
    fi
])

#------------------------------------------------------------------------
# SC_LOAD_TCLCONFIG --
#
#	Load the tclConfig.sh file
#
# Arguments:
#	
#	Requires the following vars to be set:
#		TCL_BIN_DIR
#
# Results:
#
#	Subst the following vars:
#		TCL_BIN_DIR
#		TCL_SRC_DIR
#		TCL_LIB_FILE
#
#------------------------------------------------------------------------

AC_DEFUN([SC_LOAD_TCLCONFIG], [
    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
        AC_MSG_RESULT([loading])
	. ${TCL_BIN_DIR}/tclConfig.sh
    else
        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
    fi

    # eval is required to do the TCL_DBGX substitution
    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""

    # If the TCL_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TCL_LIB_SPEC will be set to the value
    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
    if test -f "${TCL_BIN_DIR}/Makefile" ; then
        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
    elif test "`uname -s`" = "Darwin"; then
	# If Tcl was built as a framework, attempt to use the libraries
	# from the framework at the given location so that linking works
	# against Tcl.framework installed in an arbitary location.
	case ${TCL_DEFS} in
	    *TCL_FRAMEWORK*)
		if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
		    for i in "`cd ${TCL_BIN_DIR}; pwd`" \
			     "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
			if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
			    TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
			    break
			fi
		    done
		fi
		if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
		    TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
		    TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
		fi
		;;
	esac
    fi

    # eval is required to do the TCL_DBGX substitution
    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""

    AC_SUBST(TCL_VERSION)
    AC_SUBST(TCL_PATCH_LEVEL)
    AC_SUBST(TCL_BIN_DIR)
    AC_SUBST(TCL_SRC_DIR)

    AC_SUBST(TCL_LIB_FILE)
    AC_SUBST(TCL_LIB_FLAG)
    AC_SUBST(TCL_LIB_SPEC)

    AC_SUBST(TCL_STUB_LIB_FILE)
    AC_SUBST(TCL_STUB_LIB_FLAG)
    AC_SUBST(TCL_STUB_LIB_SPEC)
])

#------------------------------------------------------------------------
# SC_LOAD_TKCONFIG --
#
#	Load the tkConfig.sh file
#
# Arguments:
#	
#	Requires the following vars to be set:
#		TK_BIN_DIR
#
# Results:
#
#	Sets the following vars that should be in tkConfig.sh:
#		TK_BIN_DIR
#------------------------------------------------------------------------

AC_DEFUN([SC_LOAD_TKCONFIG], [
    AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])

    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
        AC_MSG_RESULT([loading])
	. "${TK_BIN_DIR}/tkConfig.sh"
    else
        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
    fi

    # eval is required to do the TK_DBGX substitution
    eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
    eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""

    # If the TK_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TK_LIB_SPEC will be set to the value
    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
    # instead of TK_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
    if test -f "${TK_BIN_DIR}/Makefile" ; then
        TK_LIB_SPEC=${TK_BUILD_LIB_SPEC}
        TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC}
        TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH}
    elif test "`uname -s`" = "Darwin"; then
	# If Tk was built as a framework, attempt to use the libraries
	# from the framework at the given location so that linking works
	# against Tk.framework installed in an arbitary location.
	case ${TK_DEFS} in
	    *TK_FRAMEWORK*)
		if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
		    for i in "`cd ${TK_BIN_DIR}; pwd`" \
			     "`cd ${TK_BIN_DIR}/../..; pwd`"; do
			if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
			    TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}"
			    break
			fi
		    done
		fi
		if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
		    TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}"
		    TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
		fi
		;;
	esac
    fi

    # eval is required to do the TK_DBGX substitution
    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""

    AC_SUBST(TK_VERSION)
    AC_SUBST(TK_BIN_DIR)
    AC_SUBST(TK_SRC_DIR)

    AC_SUBST(TK_LIB_FILE)
    AC_SUBST(TK_LIB_FLAG)
    AC_SUBST(TK_LIB_SPEC)

    AC_SUBST(TK_STUB_LIB_FILE)
    AC_SUBST(TK_STUB_LIB_FLAG)
    AC_SUBST(TK_STUB_LIB_SPEC)
])

#------------------------------------------------------------------------
# SC_PROG_TCLSH
#	Locate a tclsh shell installed on the system path. This macro
#	will only find a Tcl shell that already exists on the system.
#	It will not find a Tcl shell in the Tcl build directory or
#	a Tcl shell that has been installed from the Tcl build directory.
#	If a Tcl shell can't be located on the PATH, then TCLSH_PROG will
#	be set to "". Extensions should take care not to create Makefile
#	rules that are run by default and depend on TCLSH_PROG. An
#	extension can't assume that an executable Tcl shell exists at
#	build time.
#
# Arguments
#	none
#
# Results
#	Subst's the following values:
#		TCLSH_PROG
#------------------------------------------------------------------------

AC_DEFUN([SC_PROG_TCLSH], [
    AC_MSG_CHECKING([for tclsh])
    AC_CACHE_VAL(ac_cv_path_tclsh, [
	search_path=`echo ${PATH} | sed -e 's/:/ /g'`
	for dir in $search_path ; do
	    for j in `ls -r $dir/tclsh[[8-9]]* 2> /dev/null` \
		    `ls -r $dir/tclsh* 2> /dev/null` ; do
		if test x"$ac_cv_path_tclsh" = x ; then
		    if test -f "$j" ; then
			ac_cv_path_tclsh=$j
			break
		    fi
		fi
	    done
	done
    ])

    if test -f "$ac_cv_path_tclsh" ; then
	TCLSH_PROG="$ac_cv_path_tclsh"
	AC_MSG_RESULT([$TCLSH_PROG])
    else
	# It is not an error if an installed version of Tcl can't be located.
	TCLSH_PROG=""
	AC_MSG_RESULT([No tclsh found on PATH])
    fi
    AC_SUBST(TCLSH_PROG)
])

#------------------------------------------------------------------------
# SC_BUILD_TCLSH
#	Determine the fully qualified path name of the tclsh executable
#	in the Tcl build directory. This macro will correctly determine
#	the name of the tclsh executable even if tclsh has not yet
#	been built in the build directory. The build tclsh must be used
#	when running tests from an extension build directory. It is not
#	correct to use the TCLSH_PROG in cases like this.
#
# Arguments
#	none
#
# Results
#	Subst's the following values:
#		BUILD_TCLSH
#------------------------------------------------------------------------

AC_DEFUN([SC_BUILD_TCLSH], [
    AC_MSG_CHECKING([for tclsh in Tcl build directory])
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh
    AC_MSG_RESULT([$BUILD_TCLSH])
    AC_SUBST(BUILD_TCLSH)
])

#------------------------------------------------------------------------
# SC_ENABLE_SHARED --
#
#	Allows the building of shared libraries
#
# Arguments:
#	none
#	
# Results:
#
#	Adds the following arguments to configure:
#		--enable-shared=yes|no
#
#	Defines the following vars:
#		STATIC_BUILD	Used for building import/export libraries
#				on Windows.
#
#	Sets the following vars:
#		SHARED_BUILD	Value of 1 or 0
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SHARED], [
    AC_MSG_CHECKING([how to build libraries])
    AC_ARG_ENABLE(shared,
	AC_HELP_STRING([--enable-shared],
	    [build and link with shared libraries (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])

    if test "${enable_shared+set}" = set; then
	enableval="$enable_shared"
	tcl_ok=$enableval
    else
	tcl_ok=yes
    fi

    if test "$tcl_ok" = "yes" ; then
	AC_MSG_RESULT([shared])
	SHARED_BUILD=1
    else
	AC_MSG_RESULT([static])
	SHARED_BUILD=0
	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
    fi
])

#------------------------------------------------------------------------
# SC_ENABLE_FRAMEWORK --
#
#	Allows the building of shared libraries into frameworks
#
# Arguments:
#	none
#	
# Results:
#
#	Adds the following arguments to configure:
#		--enable-framework=yes|no
#
#	Sets the following vars:
#		FRAMEWORK_BUILD	Value of 1 or 0
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_FRAMEWORK], [
    if test "`uname -s`" = "Darwin" ; then
	AC_MSG_CHECKING([how to package libraries])
	AC_ARG_ENABLE(framework,
	    AC_HELP_STRING([--enable-framework],
		[package shared libraries in MacOSX frameworks (default: off)]),
	    [enable_framework=$enableval], [enable_framework=no])
	if test $enable_framework = yes; then
	    if test $SHARED_BUILD = 0; then
		AC_MSG_WARN([Frameworks can only be built if --enable-shared is yes])
		enable_framework=no
	    fi
	    if test $tcl_corefoundation = no; then
		AC_MSG_WARN([Frameworks can only be used when CoreFoundation is available])
		enable_framework=no
	    fi
	fi
	if test $enable_framework = yes; then
	    AC_MSG_RESULT([framework])
	    FRAMEWORK_BUILD=1
	else
	    if test $SHARED_BUILD = 1; then
		AC_MSG_RESULT([shared library])
	    else
		AC_MSG_RESULT([static library])
	    fi
	    FRAMEWORK_BUILD=0
	fi
    fi
])

#------------------------------------------------------------------------
# SC_ENABLE_THREADS --
#
#	Specify if thread support should be enabled
#
# Arguments:
#	none
#	
# Results:
#
#	Adds the following arguments to configure:
#		--enable-threads
#
#	Sets the following vars:
#		THREADS_LIBS	Thread library(s)
#
#	Defines the following vars:
#		TCL_THREADS
#		_REENTRANT
#		_THREAD_SAFE
#
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_THREADS], [
    AC_ARG_ENABLE(threads,
	AC_HELP_STRING([--enable-threads],
	    [build with threads (default: off)]),
	[tcl_ok=$enableval], [tcl_ok=no])

    if test "${TCL_THREADS}" = 1; then
	tcl_threaded_core=1;
    fi

    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
	TCL_THREADS=1
	# USE_THREAD_ALLOC tells us to try the special thread-based
	# allocator that significantly reduces lock contention
	AC_DEFINE(USE_THREAD_ALLOC, 1,
	    [Do we want to use the threaded memory allocator?])
	AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
	if test "`uname -s`" = "SunOS" ; then
	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
		    [Do we really want to follow the standard? Yes we do!])
	fi
	AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
	AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
	if test "$tcl_ok" = "no"; then
	    # Check a little harder for __pthread_mutex_init in the same
	    # library, as some systems hide it there until pthread.h is
	    # defined.  We could alternatively do an AC_TRY_COMPILE with
	    # pthread.h, but that will work with libpthread really doesn't
	    # exist, like AIX 4.2.  [Bug: 4359]
	    AC_CHECK_LIB(pthread, __pthread_mutex_init,
		tcl_ok=yes, tcl_ok=no)
	fi

	if test "$tcl_ok" = "yes"; then
	    # The space is needed
	    THREADS_LIBS=" -lpthread"
	else
	    AC_CHECK_LIB(pthreads, pthread_mutex_init,
		tcl_ok=yes, tcl_ok=no)
	    if test "$tcl_ok" = "yes"; then
		# The space is needed
		THREADS_LIBS=" -lpthreads"
	    else
		AC_CHECK_LIB(c, pthread_mutex_init,
		    tcl_ok=yes, tcl_ok=no)
		if test "$tcl_ok" = "no"; then
		    AC_CHECK_LIB(c_r, pthread_mutex_init,
			tcl_ok=yes, tcl_ok=no)
		    if test "$tcl_ok" = "yes"; then
			# The space is needed
			THREADS_LIBS=" -pthread"
		    else
			TCL_THREADS=0
			AC_MSG_WARN([Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile...])
		    fi
		fi
	    fi
	fi

	# Does the pthread-implementation provide
	# 'pthread_attr_setstacksize' ?

	ac_saved_libs=$LIBS
	LIBS="$LIBS $THREADS_LIBS"
	AC_CHECK_FUNCS(pthread_attr_setstacksize)
	AC_CHECK_FUNC(pthread_attr_get_np,tcl_ok=yes,tcl_ok=no)
	if test $tcl_ok = yes ; then
	    AC_DEFINE(HAVE_PTHREAD_ATTR_GET_NP, 1,
		[Do we want a BSD-like thread-attribute interface?])
	    AC_CACHE_CHECK([for pthread_attr_get_np declaration],
		tcl_cv_grep_pthread_attr_get_np, [
		AC_EGREP_HEADER(pthread_attr_get_np, pthread.h,
		    tcl_cv_grep_pthread_attr_get_np=present,
		    tcl_cv_grep_pthread_attr_get_np=missing)])
	    if test $tcl_cv_grep_pthread_attr_get_np = missing ; then
		AC_DEFINE(ATTRGETNP_NOT_DECLARED, 1,
		    [Is pthread_attr_get_np() declared in <pthread.h>?])
	    fi
	else
	    AC_CHECK_FUNC(pthread_getattr_np,tcl_ok=yes,tcl_ok=no)
	    if test $tcl_ok = yes ; then
		AC_DEFINE(HAVE_PTHREAD_GETATTR_NP, 1,
		    [Do we want a Linux-like thread-attribute interface?])
		AC_CACHE_CHECK([for pthread_getattr_np declaration],
		    tcl_cv_grep_pthread_getattr_np, [
		    AC_EGREP_HEADER(pthread_getattr_np, pthread.h,
			tcl_cv_grep_pthread_getattr_np=present,
			tcl_cv_grep_pthread_getattr_np=missing)])
		if test $tcl_cv_grep_pthread_getattr_np = missing ; then
		    AC_DEFINE(GETATTRNP_NOT_DECLARED, 1,
			[Is pthread_getattr_np declared in <pthread.h>?])
		fi
	    fi
	fi
	if test $tcl_ok = no; then
	    # Darwin thread stacksize API
	    AC_CHECK_FUNCS(pthread_get_stacksize_np)
	fi
	LIBS=$ac_saved_libs
    else
	TCL_THREADS=0
    fi
    # Do checking message here to not mess up interleaved configure output
    AC_MSG_CHECKING([for building with threads])
    if test "${TCL_THREADS}" = 1; then
	AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
	if test "${tcl_threaded_core}" = 1; then
	    AC_MSG_RESULT([yes (threaded core)])
	else
	    AC_MSG_RESULT([yes])
	fi
    else
	AC_MSG_RESULT([no (default)])
    fi

    AC_SUBST(TCL_THREADS)
])

#------------------------------------------------------------------------
# SC_ENABLE_SYMBOLS --
#
#	Specify if debugging symbols should be used.
#	Memory (TCL_MEM_DEBUG) and compile (TCL_COMPILE_DEBUG) debugging
#	can also be enabled.
#
# Arguments:
#	none
#	
#	Requires the following vars to be set in the Makefile:
#		CFLAGS_DEBUG
#		CFLAGS_OPTIMIZE
#		LDFLAGS_DEBUG
#		LDFLAGS_OPTIMIZE
#	
# Results:
#
#	Adds the following arguments to configure:
#		--enable-symbols
#
#	Defines the following vars:
#		CFLAGS_DEFAULT	Sets to $(CFLAGS_DEBUG) if true
#				Sets to $(CFLAGS_OPTIMIZE) if false
#		LDFLAGS_DEFAULT	Sets to $(LDFLAGS_DEBUG) if true
#				Sets to $(LDFLAGS_OPTIMIZE) if false
#		DBGX		Formerly used as debug library extension;
#				always blank now.
#
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SYMBOLS], [
    AC_MSG_CHECKING([for build with symbols])
    AC_ARG_ENABLE(symbols,
	AC_HELP_STRING([--enable-symbols],
	    [build with debugging symbols (default: off)]),
	[tcl_ok=$enableval], [tcl_ok=no])
# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
    DBGX=""
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
	AC_MSG_RESULT([no])
	AC_DEFINE(TCL_CFG_OPTIMIZED, 1, [Is this an optimized build?])
    else
	CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
	LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
	if test "$tcl_ok" = "yes"; then
	    AC_MSG_RESULT([yes (standard debugging)])
	fi
    fi
    AC_SUBST(CFLAGS_DEFAULT)
    AC_SUBST(LDFLAGS_DEFAULT)
    ### FIXME: Surely TCL_CFG_DEBUG should be set to whether we're debugging?
    AC_DEFINE(TCL_CFG_DEBUG, 1, [Is debugging enabled?])

    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
	AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
    fi

    ifelse($1,bccdebug,dnl Only enable 'compile' for the Tcl core itself
	if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then
	    AC_DEFINE(TCL_COMPILE_DEBUG, 1, [Is bytecode debugging enabled?])
	    AC_DEFINE(TCL_COMPILE_STATS, 1, [Are bytecode statistics enabled?])
	fi)

    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
	if test "$tcl_ok" = "all"; then
	    AC_MSG_RESULT([enabled symbols mem ]ifelse($1,bccdebug,[compile ])[debugging])
	else
	    AC_MSG_RESULT([enabled $tcl_ok debugging])
	fi
    fi
])

#------------------------------------------------------------------------
# SC_ENABLE_LANGINFO --
#
#	Allows use of modern nl_langinfo check for better l10n.
#	This is only relevant for Unix.
#
# Arguments:
#	none
#	
# Results:
#
#	Adds the following arguments to configure:
#		--enable-langinfo=yes|no (default is yes)
#
#	Defines the following vars:
#		HAVE_LANGINFO	Triggers use of nl_langinfo if defined.
#
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_LANGINFO], [
    AC_ARG_ENABLE(langinfo,
	AC_HELP_STRING([--enable-langinfo],
	    [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
	[langinfo_ok=$enableval], [langinfo_ok=yes])

    HAVE_LANGINFO=0
    if test "$langinfo_ok" = "yes"; then
	AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
    fi
    AC_MSG_CHECKING([whether to use nl_langinfo])
    if test "$langinfo_ok" = "yes"; then
	AC_CACHE_VAL(tcl_cv_langinfo_h, [
	    AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
		    [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
	AC_MSG_RESULT([$tcl_cv_langinfo_h])
	if test $tcl_cv_langinfo_h = yes; then
	    AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
	fi
    else 
	AC_MSG_RESULT([$langinfo_ok])
    fi
])

#--------------------------------------------------------------------
# SC_CONFIG_MANPAGES
#	
#	Decide whether to use symlinks for linking the manpages,
#	whether to compress the manpages after installation, and
#	whether to add a package name suffix to the installed
#	manpages to avoidfile name clashes.
#	If compression is enabled also find out what file name suffix
#	the given compression program is using.
#
# Arguments:
#	none
#
# Results:
#
#	Adds the following arguments to configure:
#		--enable-man-symlinks
#		--enable-man-compression=PROG
#		--enable-man-suffix[=STRING]
#
#	Defines the following variable:
#
#	MAN_FLAGS -	The apropriate flags for installManPage
#			according to the user's selection.
#
#--------------------------------------------------------------------

AC_DEFUN([SC_CONFIG_MANPAGES], [
    AC_MSG_CHECKING([whether to use symlinks for manpages])
    AC_ARG_ENABLE(man-symlinks,
	AC_HELP_STRING([--enable-man-symlinks],
	    [use symlinks for the manpages (default: off)]),
	test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks",
	enableval="no")
    AC_MSG_RESULT([$enableval])

    AC_MSG_CHECKING([whether to compress the manpages])
    AC_ARG_ENABLE(man-compression,
	AC_HELP_STRING([--enable-man-compression=PROG],
	    [compress the manpages with PROG (default: off)]),
	[case $enableval in
	    yes) AC_MSG_ERROR([missing argument to --enable-man-compression]);;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --compress $enableval";;
	esac],
	enableval="no")
    AC_MSG_RESULT([$enableval])
    if test "$enableval" != "no"; then
	AC_MSG_CHECKING([for compressed file suffix])
	touch TeST
	$enableval TeST
	Z=`ls TeST* | sed 's/^....//'`
	rm -f TeST*
	MAN_FLAGS="$MAN_FLAGS --extension $Z"
	AC_MSG_RESULT([$Z])
    fi

    AC_MSG_CHECKING([whether to add a package name suffix for the manpages])
    AC_ARG_ENABLE(man-suffix,
	AC_HELP_STRING([--enable-man-suffix=STRING],
	    [use STRING as a suffix to manpage file names (default: no, AC_PACKAGE_NAME if enabled without specifying STRING)]),
	[case $enableval in
	    yes) enableval="AC_PACKAGE_NAME" MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	esac],
	enableval="no")
    AC_MSG_RESULT([$enableval])

    AC_SUBST(MAN_FLAGS)
])

#--------------------------------------------------------------------
# SC_CONFIG_SYSTEM
#
#	Determine what the system is (some things cannot be easily checked
#	on a feature-driven basis, alas). This can usually be done via the
#	"uname" command, but there are a few systems, like Next, where
#	this doesn't work.
#
# Arguments:
#	none
#
# Results:
#	Defines the following var:
#
#	system -	System/platform/version identification code.
#
#--------------------------------------------------------------------

AC_DEFUN([SC_CONFIG_SYSTEM], [
    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
	if test -f /usr/lib/NextStep/software_version; then
	    tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
	else
	    tcl_cv_sys_version=`uname -s`-`uname -r`
	    if test "$?" -ne 0 ; then
		AC_MSG_WARN([can't find uname command])
		tcl_cv_sys_version=unknown
	    else
		# Special check for weird MP-RAS system (uname returns weird
		# results, and the version is kept in special file).

		if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
		    tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid`
		fi
		if test "`uname -s`" = "AIX" ; then
		    tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
		fi
	    fi
	fi
    ])
    system=$tcl_cv_sys_version
])

#--------------------------------------------------------------------
# SC_CONFIG_CFLAGS
#
#	Try to determine the proper flags to pass to the compiler
#	for building shared libraries and other such nonsense.
#
# Arguments:
#	none
#
# Results:
#
#	Defines and substitutes the following vars:
#
#       DL_OBJS -       Name of the object file that implements dynamic
#                       loading for Tcl on this system.
#       DL_LIBS -       Library file(s) to include in tclsh and other base
#                       applications in order for the "load" command to work.
#       LDFLAGS -      Flags to pass to the compiler when linking object
#                       files into an executable application binary such
#                       as tclsh.
#       LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
#                       that tell the run-time dynamic linker where to look
#                       for shared libraries such as libtcl.so.  Depends on
#                       the variable LIB_RUNTIME_DIR in the Makefile. Could
#                       be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
#       CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
#                       that tell the run-time dynamic linker where to look
#                       for shared libraries such as libtcl.so.  Depends on
#                       the variable LIB_RUNTIME_DIR in the Makefile.
#       MAKE_LIB -      Command to execute to build the a library;
#                       differs when building shared or static.
#       MAKE_STUB_LIB -
#                       Command to execute to build a stub library.
#       INSTALL_LIB -   Command to execute to install a library;
#                       differs when building shared or static.
#       INSTALL_STUB_LIB -
#                       Command to execute to install a stub library.
#       STLIB_LD -      Base command to use for combining object files
#                       into a static library.
#       SHLIB_CFLAGS -  Flags to pass to cc when compiling the components
#                       of a shared library (may request position-independent
#                       code, among other things).
#       SHLIB_LD -      Base command to use for combining object files
#                       into a shared library.
#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
#                       creating shared libraries.  This symbol typically
#                       goes at the end of the "ld" commands that build
#                       shared libraries. The value of the symbol is
#                       "${LIBS}" if all of the dependent libraries should
#                       be specified when creating a shared library.  If
#                       dependent libraries should not be specified (as on
#                       SunOS 4.x, where they cause the link to fail, or in
#                       general if Tcl and Tk aren't themselves shared
#                       libraries), then this symbol has an empty string
#                       as its value.
#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
#                       extensions.  An empty string means we don't know how
#                       to use shared libraries on this platform.
# TCL_SHLIB_LD_EXTRAS - Additional element which are added to SHLIB_LD_LIBS
#  TK_SHLIB_LD_EXTRAS   for the build of Tcl and Tk, but not recorded in the
#                       tclConfig.sh, since they are only used for the build
#                       of Tcl and Tk. 
#                       Examples: MacOS X records the library version and
#                       compatibility version in the shared library.  But
#                       of course the Tcl version of this is only used for Tcl.
#       LIB_SUFFIX -    Specifies everything that comes after the "libfoo"
#                       in a static or shared library name, using the $VERSION variable
#                       to put the version in the right place.  This is used
#                       by platforms that need non-standard library names.
#                       Examples:  ${VERSION}.so.1.1 on NetBSD, since it needs
#                       to have a version after the .so, and ${VERSION}.a
#                       on AIX, since a shared library needs to have
#                       a .a extension whereas shared objects for loadable
#                       extensions have a .so extension.  Defaults to
#                       ${VERSION}${SHLIB_SUFFIX}.
#       TCL_NEEDS_EXP_FILE -
#                       1 means that an export file is needed to link to a
#                       shared library.
#       TCL_EXP_FILE -  The name of the installed export / import file which
#                       should be used to link to the Tcl shared library.
#                       Empty if Tcl is unshared.
#       TCL_BUILD_EXP_FILE -
#                       The name of the built export / import file which
#                       should be used to link to the Tcl shared library.
#                       Empty if Tcl is unshared.
#       TCL_LIBS -
#                       Libs to use when linking Tcl shell or some other
#                       shell that includes Tcl libs.
#	CFLAGS_DEBUG -
#			Flags used when running the compiler in debug mode
#	CFLAGS_OPTIMIZE -
#			Flags used when running the compiler in optimize mode
#	CFLAGS -	Additional CFLAGS added as necessary (usually 64-bit)
#
#--------------------------------------------------------------------

AC_DEFUN([SC_CONFIG_CFLAGS], [

    # Step 0.a: Enable 64 bit support?

    AC_MSG_CHECKING([if 64bit support is requested])
    AC_ARG_ENABLE(64bit,
	AC_HELP_STRING([--enable-64bit],
	    [enable 64bit support (default: off)]),
	[do64bit=$enableval], [do64bit=no])
    AC_MSG_RESULT([$do64bit])

    # Step 0.b: Enable Solaris 64 bit VIS support?

    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
    AC_ARG_ENABLE(64bit-vis,
	AC_HELP_STRING([--enable-64bit-vis],
	    [enable 64bit Sparc VIS support (default: off)]),
	[do64bitVIS=$enableval], [do64bitVIS=no])
    AC_MSG_RESULT([$do64bitVIS])

    if test "$do64bitVIS" = "yes"; then
	# Force 64bit on with VIS
	do64bit=yes
    fi

    # Step 0.c: Check if visibility support is available. Do this here so
    # that platform specific alternatives can be used below if this fails.

    AC_CACHE_CHECK([if compiler supports visibility "hidden"],
	tcl_cv_cc_visibility_hidden, [
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	AC_TRY_LINK([
	    extern __attribute__((__visibility__("hidden"))) void f(void);
	    void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
	    tcl_cv_cc_visibility_hidden=no)
	CFLAGS=$hold_cflags])
    if test $tcl_cv_cc_visibility_hidden = yes; then
	AC_DEFINE(MODULE_SCOPE,
	    [extern __attribute__((__visibility__("hidden")))],
	    [Compiler support for module scope symbols])
    fi

    # Step 1: set the variable "system" to hold the name and version number
    # for the system.

    SC_CONFIG_SYSTEM

    # Step 2: check for existence of -ldl library.  This is needed because
    # Linux can use either -ldl or -ldld for dynamic loading.

    AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)

    # Require ranlib early so we can override it in special cases below.

    AC_REQUIRE([AC_PROG_RANLIB])

    # Step 3: set configuration options based on system name and version.

    do64bit_ok=no
    LDFLAGS_ORIG="$LDFLAGS"
    # When ld needs options to work in 64-bit mode, put them in
    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
    # is disabled by the user. [Bug 1016796]
    LDFLAGS_ARCH=""
    TCL_EXPORT_FILE_SUFFIX=""
    UNSHARED_LIB_SUFFIX=""
    TCL_TRIM_DOTS='`echo ${VERSION} | tr -d .`'
    ECHO_VERSION='`echo ${VERSION}`'
    TCL_LIB_VERSIONS_OK=ok
    CFLAGS_DEBUG=-g
    CFLAGS_OPTIMIZE=-O
    if test "$GCC" = "yes" ; then
	CFLAGS_WARNING="-Wall -Wno-implicit-int"
    else
	CFLAGS_WARNING=""
    fi
    TCL_NEEDS_EXP_FILE=0
    TCL_BUILD_EXP_FILE=""
    TCL_EXP_FILE=""
dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed.
dnl AC_CHECK_TOOL(AR, ar)
    AC_CHECK_PROG(AR, ar, ar)
    if test "${AR}" = "" ; then
	AC_MSG_ERROR([Required archive tool 'ar' not found on PATH.])
    fi
    STLIB_LD='${AR} cr'
    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
    PLAT_OBJS=""
    PLAT_SRCS=""
    case $system in
	AIX-*)
	    if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then
		# AIX requires the _r compiler when gcc isn't being used
		case "${CC}" in
		    *_r)
			# ok ...
			;;
		    *)
			CC=${CC}_r
			;;
		esac
		AC_MSG_RESULT([Using $CC for compiling with threads])
	    fi
	    LIBS="$LIBS -lc"
	    SHLIB_CFLAGS=""
	    # Note: need the LIBS below, otherwise Tk won't find Tcl's
	    # symbols when dynamically loaded into tclsh.
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"

	    DL_OBJS="tclLoadDl.o"
	    LD_LIBRARY_PATH_VAR="LIBPATH"

	    # Check to enable 64-bit flags for compiler/linker on AIX 4+
	    if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then
		if test "$GCC" = "yes" ; then
		    AC_MSG_WARN([64bit mode not supported with GCC on $system])
		else 
		    do64bit_ok=yes
		    CFLAGS="$CFLAGS -q64"
		    LDFLAGS_ARCH="-q64"
		    RANLIB="${RANLIB} -X64"
		    AR="${AR} -X64"
		    SHLIB_LD_FLAGS="-b64"
		fi
	    fi

	    if test "`uname -m`" = "ia64" ; then
		# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
		# AIX-5 has dl* in libc.so
		DL_LIBS=""
		if test "$GCC" = "yes" ; then
		    CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		else
		    CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
		fi
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
	    else
		if test "$GCC" = "yes" ; then
		    SHLIB_LD='${CC} -shared'
		else
		    SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
		fi
		SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
		DL_LIBS="-ldl"
		CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
		TCL_NEEDS_EXP_FILE=1
		TCL_EXPORT_FILE_SUFFIX='${VERSION}.exp'
	    fi

	    # AIX v<=4.1 has some different flags than 4.2+
	    if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then
		AC_LIBOBJ([tclLoadAix])
		DL_LIBS="-lld"
	    fi

	    # On AIX <=v4 systems, libbsd.a has to be linked in to support
	    # non-blocking file IO.  This library has to be linked in after
	    # the MATH_LIBS or it breaks the pow() function.  The way to
	    # insure proper sequencing, is to add it to the tail of MATH_LIBS.
	    # This library also supplies gettimeofday.
	    #
	    # AIX does not have a timezone field in struct tm. When the AIX
	    # bsd library is used, the timezone global and the gettimeofday
	    # methods are to be avoided for timezone deduction instead, we
	    # deduce the timezone by comparing the localtime result on a
	    # known GMT value.

	    AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes, libbsd=no)
	    if test $libbsd = yes; then
	    	MATH_LIBS="$MATH_LIBS -lbsd"
	    	AC_DEFINE(USE_DELTA_FOR_TZ, 1, [Do we need a special AIX hack for timezones?])
	    fi
	    ;;
	BeOS*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD='${CC} -nostart'
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"

	    #-----------------------------------------------------------
	    # Check for inet_ntoa in -lbind, for BeOS (which also needs
	    # -lsocket, even if the network functions are in -lnet which
	    # is always linked to, for compatibility.
	    #-----------------------------------------------------------
	    AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
	    ;;
	BSD/OS-2.1*|BSD/OS-3*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="shlicc -r"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	BSD/OS-4.*)
	    SHLIB_CFLAGS="-export-dynamic -fPIC"
	    SHLIB_LD='${CC} -shared'
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	dgux*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD='${CC} -G'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	HP-UX-*.11.*)
	    # Use updated header definitions where possible
	    AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
	    AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
	    LIBS="$LIBS -lxnet"               # Use the XOPEN network library

	    if test "`uname -m`" = "ia64" ; then
		SHLIB_SUFFIX=".so"
	    else
		SHLIB_SUFFIX=".sl"
	    fi
	    AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
	    if test "$tcl_ok" = yes; then
		SHLIB_CFLAGS="+z"
		SHLIB_LD="ld -b"
		SHLIB_LD_LIBS='${LIBS}'
		DL_OBJS="tclLoadShl.o"
		DL_LIBS="-ldld"
		LDFLAGS="$LDFLAGS -Wl,-E"
		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
	    fi
	    if test "$GCC" = "yes" ; then
		SHLIB_LD='${CC} -shared'
		SHLIB_LD_LIBS='${LIBS}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    fi

	    # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
	    #CFLAGS="$CFLAGS +DAportable"

	    # Check to enable 64-bit flags for compiler/linker
	    if test "$do64bit" = "yes" ; then
		if test "$GCC" = "yes" ; then
		    hpux_arch=`${CC} -dumpmachine`
		    case $hpux_arch in
			hppa64*)
			    # 64-bit gcc in use.  Fix flags for GNU ld.
			    do64bit_ok=yes
			    SHLIB_LD='${CC} -shared'
			    SHLIB_LD_LIBS='${LIBS}'
			    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
			    ;;
			*)
			    AC_MSG_WARN([64bit mode not supported with GCC on $system])
			    ;;
		    esac
		else
		    do64bit_ok=yes
		    CFLAGS="$CFLAGS +DD64"
		    LDFLAGS_ARCH="+DD64"
		fi
	    fi
	    ;;
	HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
	    SHLIB_SUFFIX=".sl"
	    AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
	    if test "$tcl_ok" = yes; then
		SHLIB_CFLAGS="+z"
		SHLIB_LD="ld -b"
		SHLIB_LD_LIBS=""
		DL_OBJS="tclLoadShl.o"
		DL_LIBS="-ldld"
		LDFLAGS="$LDFLAGS -Wl,-E"
		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
	    fi
	    ;;
	IRIX-5.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -shared -rdata_shared"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
	    ;;
	IRIX-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
	    if test "$GCC" = "yes" ; then
		CFLAGS="$CFLAGS -mabi=n32"
		LDFLAGS="$LDFLAGS -mabi=n32"
	    else
		case $system in
		    IRIX-6.3)
			# Use to build 6.2 compatible binaries on 6.3.
			CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
			;;
		    *)
			CFLAGS="$CFLAGS -n32"
			;;
		esac
		LDFLAGS="$LDFLAGS -n32"
	    fi
	    ;;
	IRIX64-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'

	    # Check to enable 64-bit flags for compiler/linker

	    if test "$do64bit" = "yes" ; then
	        if test "$GCC" = "yes" ; then
	            AC_MSG_WARN([64bit mode not supported by gcc])
	        else
	            do64bit_ok=yes
	            SHLIB_LD="ld -64 -shared -rdata_shared"
	            CFLAGS="$CFLAGS -64"
	            LDFLAGS_ARCH="-64"
	        fi
	    fi
	    ;;
	Linux*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"

	    CFLAGS_OPTIMIZE="-O2"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings 
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    if test "`uname -m`" = "alpha" ; then
		CFLAGS="$CFLAGS -mieee"
	    fi
	    if test $do64bit = yes; then
		AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
		    hold_cflags=$CFLAGS
		    CFLAGS="$CFLAGS -m64"
		    AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
		    CFLAGS=$hold_cflags])
		if test $tcl_cv_cc_m64 = yes; then
		    CFLAGS="$CFLAGS -m64"
		    do64bit_ok=yes
		fi
	    fi

	    # The combo of gcc + glibc has a bug related
	    # to inlining of functions like strtod(). The
	    # -fno-builtin flag should address this problem
	    # but it does not work. The -fno-inline flag
	    # is kind of overkill but it works.
	    # Disable inlining only when one of the
	    # files in compat/*.c is being linked in.
	    if test x"${USE_COMPAT}" != x ; then
	        CFLAGS="$CFLAGS -fno-inline"
	    fi

	    # XIM peeking works under XFree86.
	    AC_DEFINE(PEEK_XCLOSEIM, 1, [May we use XIM peeking safely?])

	    ;;
	GNU*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"

	    SHLIB_LD='${CC} -shared'
	    DL_OBJS=""
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    if test "`uname -m`" = "alpha" ; then
		CFLAGS="$CFLAGS -mieee"
	    fi
	    ;;
	Lynx*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    CFLAGS_OPTIMIZE=-02
	    SHLIB_LD='${CC} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-mshared -ldl"
	    LD_FLAGS="-Wl,--export-dynamic"
	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    ;;
	MP-RAS-02*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD='${CC} -G'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	MP-RAS-*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD='${CC} -G'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,-Bexport"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	NetBSD-*|FreeBSD-[[1-2]].*)
	    # NetBSD/SPARC needs -fPIC, -fpic will not do.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
	    AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
		AC_EGREP_CPP(yes, [
#ifdef __ELF__
	yes
#endif
		], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
	    if test $tcl_cv_ld_elf = yes; then
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
	    else
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
	    fi

	    # Ancient FreeBSD doesn't handle version numbers with dots.

	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	OpenBSD-*)
	    # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do.
	    case `machine` in
	    sparc|sparc64)
		SHLIB_CFLAGS="-fPIC";;
	    *)
		SHLIB_CFLAGS="-fpic";;
	    esac
	    SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
	    AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
		AC_EGREP_CPP(yes, [
#ifdef __ELF__
	yes
#endif
		], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
	    if test $tcl_cv_ld_elf = yes; then
		LDFLAGS=-Wl,-export-dynamic
	    else
		LDFLAGS=""
	    fi

	    # OpenBSD doesn't do version numbers with dots.
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	FreeBSD-*)
	    # FreeBSD 3.* and greater have ELF.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
	    if test "${TCL_THREADS}" = "1" ; then
		# The -pthread needs to go in the CFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"
	    fi
	    case $system in
	    FreeBSD-3.*)
	    	# FreeBSD-3 doesn't handle version numbers with dots.
	    	UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    	SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
	    	TCL_LIB_VERSIONS_OK=nodots
		;;
	    esac
	    ;;
	Darwin-*)
	    CFLAGS_OPTIMIZE="-Os"
	    SHLIB_CFLAGS="-fno-common"
	    # To avoid discrepancies between what headers configure sees during
	    # preprocessing tests and compiling tests, move any -isysroot and
	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
	    CFLAGS="`echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
	    if test $do64bit = yes; then
		case `arch` in
		    ppc)
			AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
				tcl_cv_cc_arch_ppc64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
				    tcl_cv_cc_arch_ppc64=no)
			    CFLAGS=$hold_cflags])
			if test $tcl_cv_cc_arch_ppc64 = yes; then
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    do64bit_ok=yes
			fi;;
		    i386)
			AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
				tcl_cv_cc_arch_x86_64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch x86_64"
			    AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
				    tcl_cv_cc_arch_x86_64=no)
			    CFLAGS=$hold_cflags])
			if test $tcl_cv_cc_arch_x86_64 = yes; then
			    CFLAGS="$CFLAGS -arch x86_64"
			    do64bit_ok=yes
			fi;;
		    *)
			AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
		esac
	    else
		# Check for combined 32-bit and 64-bit fat build
		echo "$CFLAGS " | grep -E -q -- '-arch (ppc64|x86_64) ' && \
		    echo "$CFLAGS " | grep -E -q -- '-arch (ppc|i386) ' && \
		    fat_32_64=yes
	    fi
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'
	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
		LDFLAGS=$hold_ldflags])
	    if test $tcl_cv_ld_single_module = yes; then
		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
	    fi
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".dylib"
	    DL_OBJS="tclLoadDyld.o"
	    DL_LIBS=""
	    # Don't use -prebind when building for Mac OS X 10.4 or later only:
	    test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
		"`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4 && \
		LDFLAGS="$LDFLAGS -prebind"
	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes, tcl_cv_ld_search_paths_first=no)
		LDFLAGS=$hold_ldflags])
	    if test $tcl_cv_ld_search_paths_first = yes; then
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
	    fi
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
	    PLAT_OBJS='${MAC_OSX_OBJS}'
	    PLAT_SRCS='${MAC_OSX_SRCS}'
	    AC_MSG_CHECKING([whether to use CoreFoundation])
	    AC_ARG_ENABLE(corefoundation,
		AC_HELP_STRING([--enable-corefoundation],
		    [use CoreFoundation API on MacOSX (default: on)]),
		[tcl_corefoundation=$enableval], [tcl_corefoundation=yes])
	    AC_MSG_RESULT([$tcl_corefoundation])
	    if test $tcl_corefoundation = yes; then
		AC_CACHE_CHECK([for CoreFoundation.framework], tcl_cv_lib_corefoundation, [
		    hold_libs=$LIBS
		    if test "$fat_32_64" = yes; then for v in CFLAGS CPPFLAGS LDFLAGS; do
			# On Tiger there is no 64-bit CF, so remove 64-bit archs
			# from CFLAGS et al. while testing for presence of CF.
			# 64-bit CF is disabled in tclUnixPort.h if necessary.
			eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
		    done; fi
		    LIBS="$LIBS -framework CoreFoundation"
		    AC_TRY_LINK([#include <CoreFoundation/CoreFoundation.h>], 
			[CFBundleRef b = CFBundleGetMainBundle();], 
			tcl_cv_lib_corefoundation=yes, tcl_cv_lib_corefoundation=no)
		    if test "$fat_32_64" = yes; then for v in CFLAGS CPPFLAGS LDFLAGS; do
			eval $v'="$hold_'$v'"'
		    done; fi; LIBS=$hold_libs])
		if test $tcl_cv_lib_corefoundation = yes; then
		    LIBS="$LIBS -framework CoreFoundation"
		    AC_DEFINE(HAVE_COREFOUNDATION, 1, 
			[Do we have access to Darwin CoreFoundation.framework?])
		else
		    tcl_corefoundation=no
		fi
		if test "$fat_32_64" = yes -a $tcl_corefoundation = yes; then
		    AC_CACHE_CHECK([for 64-bit CoreFoundation], tcl_cv_lib_corefoundation_64, [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
			done
			AC_TRY_LINK([#include <CoreFoundation/CoreFoundation.h>], 
			    [CFBundleRef b = CFBundleGetMainBundle();], 
			    tcl_cv_lib_corefoundation_64=yes, tcl_cv_lib_corefoundation_64=no)
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
			done])
		    if test $tcl_cv_lib_corefoundation_64 = no; then
			AC_DEFINE(NO_COREFOUNDATION_64, 1,
			    [Is Darwin CoreFoundation unavailable for 64-bit?])
                        LDFLAGS="$LDFLAGS -Wl,-no_arch_warnings"
		    fi
		fi
	    fi
	    if test "$tcl_cv_cc_visibility_hidden" != yes; then
		AC_DEFINE(MODULE_SCOPE, [__private_extern__],
		    [Compiler support for module scope symbols])
	    fi
	    AC_DEFINE(MAC_OSX_TCL, 1, [Is this a Mac I see before me?])
	    ;;
	NEXTSTEP-*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD='${CC} -nostdlib -r'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadNext.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OS/390-*)
	    CFLAGS_OPTIMIZE=""		# Optimizer is buggy
	    AC_DEFINE(_OE_SOCKETS, 1,	# needed in sys/socket.h
		[Should OS/390 do the right thing with sockets?])
	    ;;      
	OSF1-1.0|OSF1-1.1|OSF1-1.2)
	    # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
	    SHLIB_CFLAGS=""
	    # Hack: make package name same as library name
	    SHLIB_LD='ld -R -export $@:'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadOSF.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OSF1-1.*)
	    # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
	    SHLIB_CFLAGS="-fPIC"
	    if test "$SHARED_BUILD" = "1" ; then
	        SHLIB_LD="ld -shared"
	    else
	        SHLIB_LD="ld -non_shared"
	    fi
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OSF1-V*)
	    # Digital OSF/1
	    SHLIB_CFLAGS=""
	    if test "$SHARED_BUILD" = "1" ; then
	        SHLIB_LD='ld -shared -expect_unresolved "*"'
	    else
	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'
	    fi
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
	    if test "$GCC" = "yes" ; then
		CFLAGS="$CFLAGS -mieee"
            else
		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
	    fi
	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
	    if test "${TCL_THREADS}" = "1" ; then
		CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
		CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
		LIBS=`echo $LIBS | sed s/-lpthreads//`
		if test "$GCC" = "yes" ; then
		    LIBS="$LIBS -lpthread -lmach -lexc"
		else
		    CFLAGS="$CFLAGS -pthread"
		    LDFLAGS="$LDFLAGS -pthread"
		fi
	    fi

	    ;;
	QNX-6*)
	    # QNX RTP
	    # This may work for all QNX, but it was only reported for v6.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    # dlopen is in -lc on QNX
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SCO_SV-3.2*)
	    # Note, dlopen is available only on SCO 3.2.5 and greater. However,
	    # this test works, since "uname -s" was non-standard in 3.2.4 and
	    # below.
	    if test "$GCC" = "yes" ; then
	    	SHLIB_CFLAGS="-fPIC -melf"
	    	LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
	    else
	    	SHLIB_CFLAGS="-Kpic -belf"
	    	LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
	    fi
	    SHLIB_LD="ld -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SINIX*5.4*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD='${CC} -G'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SunOS-4*)
	    SHLIB_CFLAGS="-PIC"
	    SHLIB_LD="ld"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

	    # SunOS can't handle version numbers with dots in them in library
	    # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
	    # requires an extra version number at the end of .so file names.
	    # So, the library has to have a name like libtcl75.so.1.0

	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	SunOS-5.[[0-6]])
	    # Careful to not let 5.10+ fall into this case

	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.

	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
		[Do we really want to follow the standard? Yes we do!])

	    SHLIB_CFLAGS="-KPIC"

	    # Note: need the LIBS below, otherwise Tk won't find Tcl's
	    # symbols when dynamically loaded into tclsh.

	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    if test "$GCC" = "yes" ; then
		SHLIB_LD='${CC} -shared'
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    else
		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
		CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    fi
	    ;;
	SunOS-5*)
	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.

	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
		[Do we really want to follow the standard? Yes we do!])

	    SHLIB_CFLAGS="-KPIC"

	    # Check to enable 64-bit flags for compiler/linker
	    if test "$do64bit" = "yes" ; then
		arch=`isainfo`
		if test "$arch" = "sparcv9 sparc" ; then
			if test "$GCC" = "yes" ; then
			    if test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt "3" ; then
				AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
			    else
				do64bit_ok=yes
				CFLAGS="$CFLAGS -m64 -mcpu=v9"
				LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
				SHLIB_CFLAGS="-fPIC"
			    fi
			else
			    do64bit_ok=yes
			    if test "$do64bitVIS" = "yes" ; then
				CFLAGS="$CFLAGS -xarch=v9a"
			    	LDFLAGS_ARCH="-xarch=v9a"
			    else
				CFLAGS="$CFLAGS -xarch=v9"
			    	LDFLAGS_ARCH="-xarch=v9"
			    fi
			    # Solaris 64 uses this as well
			    #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
			fi
		elif test "$arch" = "amd64 i386" ; then
		    if test "$GCC" = "yes" ; then
			AC_MSG_WARN([64bit mode not supported with GCC on $system])
		    else
			do64bit_ok=yes
			CFLAGS="$CFLAGS -xarch=amd64"
			LDFLAGS="$LDFLAGS -xarch=amd64"
		    fi
		else
		    AC_MSG_WARN([64bit mode not supported for $arch])
		fi
	    fi
	    
	    # Note: need the LIBS below, otherwise Tk won't find Tcl's
	    # symbols when dynamically loaded into tclsh.

	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    if test "$GCC" = "yes" ; then
		SHLIB_LD='${CC} -shared'
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
		if test "$do64bit_ok" = "yes" ; then
		    # We need to specify -static-libgcc or we need to
		    # add the path to the sparv9 libgcc.
		    SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
		    # for finding sparcv9 libgcc, get the regular libgcc
		    # path, remove so name and append 'sparcv9'
		    #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
		    #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
		fi
	    else
		case $system in
		    SunOS-5.[[1-9]][[0-9]]*)
			SHLIB_LD='${CC} -G -z text';;
		    *)
			SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
		esac
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
	    fi
	    ;;
	UNIX_SV* | UnixWare-5*)
	    SHLIB_CFLAGS="-KPIC"
	    SHLIB_LD='${CC} -G'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
	    # that don't grok the -Bexport option.  Test that it does.
	    AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
	        LDFLAGS=$hold_ldflags])
	    if test $tcl_cv_ld_Bexport = yes; then
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
	    fi
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
    esac

    if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
	AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
    fi

    if test "$do64bit" = "yes" -a "$do64bit_ok" = "yes" ; then
	AC_DEFINE(TCL_CFG_DO64BIT, 1, [Is this a 64-bit build?])
    fi

dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
dnl # until the end of configure, as configure's compile and link tests use
dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
dnl # preprocessing tests use only CPPFLAGS.
    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])

    # Step 4: disable dynamic loading if requested via a command-line switch.

    AC_ARG_ENABLE(load,
	AC_HELP_STRING([--enable-load],
	    [allow dynamic loading and "load" command (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])
    if test "$tcl_ok" = "no"; then
	DL_OBJS=""
    fi

    if test "x$DL_OBJS" != "x" ; then
	BUILD_DLTEST="\$(DLTEST_TARGETS)"
    else
	echo "Can't figure out how to do dynamic loading or shared libraries"
	echo "on this system."
	SHLIB_CFLAGS=""
	SHLIB_LD=""
	SHLIB_SUFFIX=""
	DL_OBJS="tclLoadNone.o"
	DL_LIBS=""
	LDFLAGS="$LDFLAGS_ORIG"
	CC_SEARCH_FLAGS=""
	LD_SEARCH_FLAGS=""
	BUILD_DLTEST=""
    fi
    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"

    # If we're running gcc, then change the C flags for compiling shared
    # libraries to the right flags for gcc, instead of those for the
    # standard manufacturer compiler.

    if test "$DL_OBJS" != "tclLoadNone.o" ; then
	if test "$GCC" = "yes" ; then
	    case $system in
		AIX-*)
		    ;;
		BSD/OS*)
		    ;;
		IRIX*)
		    ;;
		NetBSD-*|FreeBSD-*)
		    ;;
		Darwin-*)
		    ;;
		SCO_SV-3.2*)
		    ;;
		*)
		    SHLIB_CFLAGS="-fPIC"
		    ;;
	    esac
	fi
    fi

    if test "$SHARED_LIB_SUFFIX" = "" ; then
	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'
    fi
    if test "$UNSHARED_LIB_SUFFIX" = "" ; then
	UNSHARED_LIB_SUFFIX='${VERSION}.a'
    fi

    if test "${SHARED_BUILD}" = "1" && test "${SHLIB_SUFFIX}" != "" ; then
        LIB_SUFFIX=${SHARED_LIB_SUFFIX}
        MAKE_LIB='${SHLIB_LD} -o [$]@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
        INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) $(LIB_INSTALL_DIR)/$(LIB_FILE)'
    else
        LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}

        if test "$RANLIB" = "" ; then
            MAKE_LIB='$(STLIB_LD) [$]@ ${OBJS}'
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) $(LIB_INSTALL_DIR)/$(LIB_FILE)'
        else
            MAKE_LIB='${STLIB_LD} [$]@ ${OBJS} ; ${RANLIB} [$]@'
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) $(LIB_INSTALL_DIR)/$(LIB_FILE) ; (cd $(LIB_INSTALL_DIR) ; $(RANLIB) $(LIB_FILE))'
        fi

dnl        Not at all clear what this was doing in Tcl's configure.in
dnl        or why it was needed was needed. In any event, this sort of
dnl        things needs to be done in the big loop above.
dnl        REMOVE THIS BLOCK LATER! (mdejong)
dnl        case $system in
dnl            BSD/OS*)
dnl                ;;
dnl            AIX-[[1-4]].*)
dnl                ;;
dnl            *)
dnl                SHLIB_LD_LIBS=""
dnl                ;;
dnl        esac
    fi


    # Stub lib does not depend on shared/static configuration
    if test "$RANLIB" = "" ; then
        MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS}'
        INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) $(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)'
    else
        MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS} ; ${RANLIB} [$]@'
        INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) $(LIB_INSTALL_DIR)/$(STUB_LIB_FILE) ; (cd $(LIB_INSTALL_DIR) ; $(RANLIB) $(STUB_LIB_FILE))'
    fi

    # Define TCL_LIBS now that we know what DL_LIBS is.
    # The trick here is that we don't want to change
    # the value of TCL_LIBS if it is already set when
    # tclConfig.sh had been loaded by Tk.
    if test "x${TCL_LIBS}" = "x"; then
        TCL_LIBS="${DL_LIBS} ${LIBS} ${MATH_LIBS}"
    fi
    AC_SUBST(TCL_LIBS)

    # FIXME: This subst was left in only because the TCL_DL_LIBS
    # entry in tclConfig.sh uses it. It is not clear why someone
    # would use TCL_DL_LIBS instead of TCL_LIBS.
    AC_SUBST(DL_LIBS)

    AC_SUBST(DL_OBJS)
    AC_SUBST(PLAT_OBJS)
    AC_SUBST(PLAT_SRCS)
    AC_SUBST(CFLAGS)
    AC_SUBST(CFLAGS_DEBUG)
    AC_SUBST(CFLAGS_OPTIMIZE)
    AC_SUBST(CFLAGS_WARNING)

    AC_SUBST(LDFLAGS)
    AC_SUBST(LDFLAGS_DEBUG)
    AC_SUBST(LDFLAGS_OPTIMIZE)
    AC_SUBST(CC_SEARCH_FLAGS)
    AC_SUBST(LD_SEARCH_FLAGS)

    AC_SUBST(STLIB_LD)
    AC_SUBST(SHLIB_LD)
    AC_SUBST(TCL_SHLIB_LD_EXTRAS)
    AC_SUBST(TK_SHLIB_LD_EXTRAS)
    AC_SUBST(SHLIB_LD_LIBS)
    AC_SUBST(SHLIB_CFLAGS)
    AC_SUBST(SHLIB_SUFFIX)
    AC_DEFINE_UNQUOTED(TCL_SHLIB_EXT,"${SHLIB_SUFFIX}",
	[What is the default extension for shared libraries?])

    AC_SUBST(MAKE_LIB)
    AC_SUBST(MAKE_STUB_LIB)
    AC_SUBST(INSTALL_LIB)
    AC_SUBST(INSTALL_STUB_LIB)
    AC_SUBST(RANLIB)
])

#--------------------------------------------------------------------
# SC_SERIAL_PORT
#
#	Determine which interface to use to talk to the serial port.
#	Note that #include lines must begin in leftmost column for
#	some compilers to recognize them as preprocessor directives,
#	and some build environments have stdin not pointing at a
#	pseudo-terminal (usually /dev/null instead.)
#
# Arguments:
#	none
#	
# Results:
#
#	Defines only one of the following vars:
#		HAVE_SYS_MODEM_H
#		USE_TERMIOS
#		USE_TERMIO
#		USE_SGTTY
#
#--------------------------------------------------------------------

AC_DEFUN([SC_SERIAL_PORT], [
    AC_CHECK_HEADERS(sys/modem.h)
    AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
    AC_TRY_RUN([
#include <termios.h>

int main() {
    struct termios t;
    if (tcgetattr(0, &t) == 0) {
	cfsetospeed(&t, 0);
	t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
	return 0;
    }
    return 1;
}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
    if test $tcl_cv_api_serial = no ; then
	AC_TRY_RUN([
#include <termio.h>

int main() {
    struct termio t;
    if (ioctl(0, TCGETA, &t) == 0) {
	t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
	return 0;
    }
    return 1;
}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
    fi
    if test $tcl_cv_api_serial = no ; then
	AC_TRY_RUN([
#include <sgtty.h>

int main() {
    struct sgttyb t;
    if (ioctl(0, TIOCGETP, &t) == 0) {
	t.sg_ospeed = 0;
	t.sg_flags |= ODDP | EVENP | RAW;
	return 0;
    }
    return 1;
}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
    fi
    if test $tcl_cv_api_serial = no ; then
	AC_TRY_RUN([
#include <termios.h>
#include <errno.h>

int main() {
    struct termios t;
    if (tcgetattr(0, &t) == 0
	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
	cfsetospeed(&t, 0);
	t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
	return 0;
    }
    return 1;
}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
    fi
    if test $tcl_cv_api_serial = no; then
	AC_TRY_RUN([
#include <termio.h>
#include <errno.h>

int main() {
    struct termio t;
    if (ioctl(0, TCGETA, &t) == 0
	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
	t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
	return 0;
    }
    return 1;
    }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
    fi
    if test $tcl_cv_api_serial = no; then
	AC_TRY_RUN([
#include <sgtty.h>
#include <errno.h>

int main() {
    struct sgttyb t;
    if (ioctl(0, TIOCGETP, &t) == 0
	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
	t.sg_ospeed = 0;
	t.sg_flags |= ODDP | EVENP | RAW;
	return 0;
    }
    return 1;
}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
    fi])
    case $tcl_cv_api_serial in
	termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
	termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
	sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
    esac
])

#--------------------------------------------------------------------
# SC_MISSING_POSIX_HEADERS
#
#	Supply substitutes for missing POSIX header files.  Special
#	notes:
#	    - stdlib.h doesn't define strtol, strtoul, or
#	      strtod insome versions of SunOS
#	    - some versions of string.h don't declare procedures such
#	      as strstr
#
# Arguments:
#	none
#	
# Results:
#
#	Defines some of the following vars:
#		NO_DIRENT_H
#		NO_VALUES_H
#		HAVE_LIMITS_H or NO_LIMITS_H
#		NO_STDLIB_H
#		NO_STRING_H
#		NO_SYS_WAIT_H
#		NO_DLFCN_H
#		HAVE_SYS_PARAM_H
#
#		HAVE_STRING_H ?
#
#--------------------------------------------------------------------

AC_DEFUN([SC_MISSING_POSIX_HEADERS], [
    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
    AC_TRY_LINK([#include <sys/types.h>
#include <dirent.h>], [
#ifndef _POSIX_SOURCE
#   ifdef __Lynx__
	/*
	 * Generate compilation error to make the test fail:  Lynx headers
	 * are only valid if really in the POSIX environment.
	 */

	missing_procedure();
#   endif
#endif
DIR *d;
struct dirent *entryPtr;
char *p;
d = opendir("foobar");
entryPtr = readdir(d);
p = entryPtr->d_name;
closedir(d);
], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])

    if test $tcl_cv_dirent_h = no; then
	AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
    fi

    AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
    AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
    AC_CHECK_HEADER(limits.h,
	[AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
	[AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
    AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
    fi
    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)

    # See also memmove check below for a place where NO_STRING_H can be
    # set and why.

    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
    fi

    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])

    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
    AC_HAVE_HEADERS(sys/param.h)
])

#--------------------------------------------------------------------
# SC_PATH_X
#
#	Locate the X11 header files and the X11 library archive.  Try
#	the ac_path_x macro first, but if it doesn't find the X stuff
#	(e.g. because there's no xmkmf program) then check through
#	a list of possible directories.  Under some conditions the
#	autoconf macro will return an include directory that contains
#	no include files, so double-check its result just to be safe.
#
# Arguments:
#	none
#	
# Results:
#
#	Sets the the following vars:
#		XINCLUDES
#		XLIBSW
#
#--------------------------------------------------------------------

AC_DEFUN([SC_PATH_X], [
    AC_PATH_X
    not_really_there=""
    if test "$no_x" = ""; then
	if test "$x_includes" = ""; then
	    AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
	else
	    if test ! -r $x_includes/X11/Intrinsic.h; then
		not_really_there="yes"
	    fi
	fi
    fi
    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
	AC_MSG_CHECKING([for X11 header files])
	found_xincludes="no"
	AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no")
	if test "$found_xincludes" = "no"; then
	    dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
	    for i in $dirs ; do
		if test -r $i/X11/Intrinsic.h; then
		    AC_MSG_RESULT([$i])
		    XINCLUDES=" -I$i"
		    found_xincludes="yes"
		    break
		fi
	    done
	fi
    else
	if test "$x_includes" != ""; then
	    XINCLUDES="-I$x_includes"
	    found_xincludes="yes"
	fi
    fi
    if test found_xincludes = "no"; then
	AC_MSG_RESULT([couldn't find any!])
    fi

    if test "$no_x" = yes; then
	AC_MSG_CHECKING([for X11 libraries])
	XLIBSW=nope
	dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
	for i in $dirs ; do
	    if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then
		AC_MSG_RESULT([$i])
		XLIBSW="-L$i -lX11"
		x_libraries="$i"
		break
	    fi
	done
    else
	if test "$x_libraries" = ""; then
	    XLIBSW=-lX11
	else
	    XLIBSW="-L$x_libraries -lX11"
	fi
    fi
    if test "$XLIBSW" = nope ; then
	AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
    fi
    if test "$XLIBSW" = nope ; then
	AC_MSG_RESULT([could not find any!  Using -lX11.])
	XLIBSW=-lX11
    fi
])

#--------------------------------------------------------------------
# SC_BLOCKING_STYLE
#
#	The statements below check for systems where POSIX-style
#	non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. 
#	On these systems (mostly older ones), use the old BSD-style
#	FIONBIO approach instead.
#
# Arguments:
#	none
#	
# Results:
#
#	Defines some of the following vars:
#		HAVE_SYS_IOCTL_H
#		HAVE_SYS_FILIO_H
#		USE_FIONBIO
#		O_NONBLOCK
#
#--------------------------------------------------------------------

AC_DEFUN([SC_BLOCKING_STYLE], [
    AC_CHECK_HEADERS(sys/ioctl.h)
    AC_CHECK_HEADERS(sys/filio.h)
    SC_CONFIG_SYSTEM
    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
    case $system in
	# There used to be code here to use FIONBIO under AIX.  However, it
	# was reported that FIONBIO doesn't work under AIX 3.2.5.  Since
	# using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
	# code (JO, 5/31/97).

	OSF*)
	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
	    AC_MSG_RESULT([FIONBIO])
	    ;;
	SunOS-4*)
	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
	    AC_MSG_RESULT([FIONBIO])
	    ;;
	*)
	    AC_MSG_RESULT([O_NONBLOCK])
	    ;;
    esac
])

#--------------------------------------------------------------------
# SC_TIME_HANLDER
#
#	Checks how the system deals with time.h, what time structures
#	are used on the system, and what fields the structures have.
#
# Arguments:
#	none
#	
# Results:
#
#	Defines some of the following vars:
#		USE_DELTA_FOR_TZ
#		HAVE_TM_GMTOFF
#		HAVE_TM_TZADJ
#		HAVE_TIMEZONE_VAR
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TIME_HANDLER], [
    AC_CHECK_HEADERS(sys/time.h)
    AC_HEADER_TIME
    AC_STRUCT_TIMEZONE

    AC_CHECK_FUNCS(gmtime_r localtime_r mktime)

    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
	AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
	    tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
    if test $tcl_cv_member_tm_tzadj = yes ; then
	AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
    fi

    AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
	AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
	    tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
    if test $tcl_cv_member_tm_gmtoff = yes ; then
	AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
    fi

    #
    # Its important to include time.h in this check, as some systems
    # (like convex) have timezone functions, etc.
    #
    AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
	AC_TRY_COMPILE([#include <time.h>],
	    [extern long timezone;
	    timezone += 1;
	    exit (0);],
	    tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
    if test $tcl_cv_timezone_long = yes ; then
	AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
    else
	#
	# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
	#
	AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
	    AC_TRY_COMPILE([#include <time.h>],
		[extern time_t timezone;
		timezone += 1;
		exit (0);],
		tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
	if test $tcl_cv_timezone_time = yes ; then
	    AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
	fi
    fi
])

#--------------------------------------------------------------------
# SC_BUGGY_STRTOD
#
#	Under Solaris 2.4, strtod returns the wrong value for the
#	terminating character under some conditions.  Check for this
#	and if the problem exists use a substitute procedure
#	"fixstrtod" (provided by Tcl) that corrects the error.
#	Also, on Compaq's Tru64 Unix 5.0,
#	strtod(" ") returns 0.0 instead of a failure to convert.
#
# Arguments:
#	none
#	
# Results:
#
#	Might defines some of the following vars:
#		strtod (=fixstrtod)
#
#--------------------------------------------------------------------

AC_DEFUN([SC_BUGGY_STRTOD], [
    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
    if test "$tcl_strtod" = 1; then
	AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
	    AC_TRY_RUN([
		extern double strtod();
		int main() {
		    char *infString="Inf", *nanString="NaN", *spaceString=" ";
		    char *term;
		    double value;
		    value = strtod(infString, &term);
		    if ((term != infString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(nanString, &term);
		    if ((term != nanString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(spaceString, &term);
		    if (term == (spaceString+1)) {
			exit(1);
		    }
		    exit(0);
		}], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
		    tcl_cv_strtod_buggy=buggy)])
	if test "$tcl_cv_strtod_buggy" = buggy; then
	    AC_LIBOBJ([fixstrtod])
	    USE_COMPAT=1
	    AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
	fi
    fi
])

#--------------------------------------------------------------------
# SC_TCL_LINK_LIBS
#
#	Search for the libraries needed to link the Tcl shell.
#	Things like the math library (-lm) and socket stuff (-lsocket vs.
#	-lnsl) are dealt with here.
#
# Arguments:
#	None.
#	
# Results:
#
#	Might append to the following vars:
#		LIBS
#		MATH_LIBS
#
#	Might define the following vars:
#		HAVE_NET_ERRNO_H
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_LINK_LIBS], [
    #--------------------------------------------------------------------
    # On a few very rare systems, all of the libm.a stuff is
    # already in libc.a.  Set compiler flags accordingly.
    # Also, Linux requires the "ieee" library for math to work
    # right (and it must appear before "-lm").
    #--------------------------------------------------------------------

    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])

    #--------------------------------------------------------------------
    # Interactive UNIX requires -linet instead of -lsocket, plus it
    # needs net/errno.h to define the socket-related error codes.
    #--------------------------------------------------------------------

    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
    AC_CHECK_HEADER(net/errno.h, [
	AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])

    #--------------------------------------------------------------------
    #	Check for the existence of the -lsocket and -lnsl libraries.
    #	The order here is important, so that they end up in the right
    #	order in the command line generated by make.  Here are some
    #	special considerations:
    #	1. Use "connect" and "accept" to check for -lsocket, and
    #	   "gethostbyname" to check for -lnsl.
    #	2. Use each function name only once:  can't redo a check because
    #	   autoconf caches the results of the last check and won't redo it.
    #	3. Use -lnsl and -lsocket only if they supply procedures that
    #	   aren't already present in the normal libraries.  This is because
    #	   IRIX 5.2 has libraries, but they aren't needed and they're
    #	   bogus:  they goof up name resolution if used.
    #	4. On some SVR4 systems, can't use -lsocket without -lnsl too.
    #	   To get around this problem, check for both libraries together
    #	   if -lsocket doesn't work by itself.
    #--------------------------------------------------------------------

    tcl_checkBoth=0
    AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
    if test "$tcl_checkSocket" = 1; then
	AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
	    LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
    fi
    if test "$tcl_checkBoth" = 1; then
	tk_oldLibs=$LIBS
	LIBS="$LIBS -lsocket -lnsl"
	AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
    fi
    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
	    [LIBS="$LIBS -lnsl"])])
])

#--------------------------------------------------------------------
# SC_TCL_EARLY_FLAGS
#
#	Check for what flags are needed to be passed so the correct OS
#	features are available.
#
# Arguments:
#	None
#	
# Results:
#
#	Might define the following vars:
#		_ISOC99_SOURCE
#		_LARGEFILE64_SOURCE
#		_LARGEFILE_SOURCE64
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_EARLY_FLAG],[
    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
	AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
	    AC_TRY_COMPILE([[#define ]$1[ 1
]$2], $3,
		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
	AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
	tcl_flags="$tcl_flags $1"
    fi
])

AC_DEFUN([SC_TCL_EARLY_FLAGS],[
    AC_MSG_CHECKING([for required early compiler flags])
    tcl_flags=""
    SC_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
	[char *p = (char *)strtoll; char *q = (char *)strtoull;])
    SC_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
	[struct stat64 buf; int i = stat64("/", &buf);])
    SC_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
	[char *p = (char *)open64;])
    if test "x${tcl_flags}" = "x" ; then
	AC_MSG_RESULT([none])
    else
	AC_MSG_RESULT([${tcl_flags}])
    fi
])

#--------------------------------------------------------------------
# SC_TCL_64BIT_FLAGS
#
#	Check for what is defined in the way of 64-bit features.
#
# Arguments:
#	None
#	
# Results:
#
#	Might define the following vars:
#		TCL_WIDE_INT_IS_LONG
#		TCL_WIDE_INT_TYPE
#		HAVE_STRUCT_DIRENT64
#		HAVE_STRUCT_STAT64
#		HAVE_TYPE_OFF64_T
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_64BIT_FLAGS], [
    AC_MSG_CHECKING([for 64-bit integer type])
    AC_CACHE_VAL(tcl_cv_type_64bit,[
	tcl_cv_type_64bit=none
	# See if the compiler knows natively about __int64
	AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
	    tcl_type_64bit=__int64, tcl_type_64bit="long long")
	# See if we should use long anyway  Note that we substitute in the
	# type that is our current guess for a 64-bit type inside this check
	# program, so it should be modified only carefully...
        AC_TRY_COMPILE(,[switch (0) { 
            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ; 
        }],tcl_cv_type_64bit=${tcl_type_64bit})])
    if test "${tcl_cv_type_64bit}" = none ; then
	AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
	AC_MSG_RESULT([using long])
    else
	AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
	    [What type should be used to define wide integers?])
	AC_MSG_RESULT([${tcl_cv_type_64bit}])

	# Now check for auxiliary declarations
	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
	    AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/dirent.h>],[struct dirent64 p;],
		tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
	    AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
],
		tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
	fi

	AC_CHECK_FUNCS(open64 lseek64)
	AC_MSG_CHECKING([for off64_t])
	AC_CACHE_VAL(tcl_cv_type_off64_t,[
	    AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
],
		tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
	dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
	dnl functions lseek64 and open64 are defined.
	if test "x${tcl_cv_type_off64_t}" = "xyes" && \
	        test "x${ac_cv_func_lseek64}" = "xyes" && \
	        test "x${ac_cv_func_open64}" = "xyes" ; then
	    AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
	    AC_MSG_RESULT([yes])
	else
	    AC_MSG_RESULT([no])
	fi
    fi
])

#--------------------------------------------------------------------
# SC_TCL_CFG_ENCODING	TIP #59
#
#	Declare the encoding to use for embedded configuration information.
#
# Arguments:
#	None.
#
# Results:
#	Might append to the following vars:
#		DEFS	(implicit)
#
#	Will define the following vars:
#		TCL_CFGVAL_ENCODING
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CFG_ENCODING], [
    AC_ARG_WITH(encoding,
	AC_HELP_STRING([--with-encoding],
	    [encoding for configuration values (default: iso8859-1)]),
	with_tcencoding=${withval})

    if test x"${with_tcencoding}" != x ; then
	AC_DEFINE_UNQUOTED(TCL_CFGVAL_ENCODING,"${with_tcencoding}",
	    [What encoding should be used for embedded configuration info?])
    else
	AC_DEFINE(TCL_CFGVAL_ENCODING,"iso8859-1",
	    [What encoding should be used for embedded configuration info?])
    fi
])

#--------------------------------------------------------------------
# SC_TCL_CHECK_BROKEN_FUNC
#
#	Check for broken function.
#
# Arguments:
#	funcName - function to test for
#	advancedTest - the advanced test to run if the function is present
#
# Results:
#	Might cause compatability versions of the function to be used.
#	Might affect the following vars:
#		USE_COMPAT	(implicit)
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CHECK_BROKEN_FUNC],[
    AC_CHECK_FUNC($1, tcl_ok=1, tcl_ok=0)
    if test ["$tcl_ok"] = 1; then
	AC_CACHE_CHECK([proper ]$1[ implementation], [tcl_cv_]$1[_unbroken],
	    AC_TRY_RUN([[int main() {]$2[}]],[tcl_cv_]$1[_unbroken]=ok,
		[tcl_cv_]$1[_unbroken]=broken,[tcl_cv_]$1[_unbroken]=unknown))
	if test ["$tcl_cv_]$1[_unbroken"] = "ok"; then
	    tcl_ok=1
	else
	    tcl_ok=0
	fi
    fi
    if test ["$tcl_ok"] = 0; then
	AC_LIBOBJ($1)
	USE_COMPAT=1
    fi
])

#--------------------------------------------------------------------
# SC_TCL_GETHOSTBYADDR_R
#
#	Check if we have MT-safe variant of gethostbyaddr().
#
# Arguments:
#	None
#	
# Results:
#
#	Might define the following vars:
#		HAVE_GETHOSTBYADDR_R
#		HAVE_GETHOSTBYADDR_R_7
#		HAVE_GETHOSTBYADDR_R_8
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETHOSTBYADDR_R], [AC_CHECK_FUNC(gethostbyaddr_r, [
    AC_CACHE_CHECK([for gethostbyaddr_r with 7 args], tcl_cv_api_gethostbyaddr_r_7, [
    AC_TRY_COMPILE([
	#include <netdb.h>
    ], [
	char *addr;
	int length;
	int type;
	struct hostent *result;
	char buffer[2048];
	int buflen = 2048;
	int h_errnop;

	(void) gethostbyaddr_r(addr, length, type, result, buffer, buflen,
			       &h_errnop);
    ], tcl_cv_api_gethostbyaddr_r_7=yes, tcl_cv_api_gethostbyaddr_r_7=no)])
    tcl_ok=$tcl_cv_api_gethostbyaddr_r_7
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYADDR_R_7, 1,
	    [Define to 1 if gethostbyaddr_r takes 7 args.])
    else
	AC_CACHE_CHECK([for gethostbyaddr_r with 8 args], tcl_cv_api_gethostbyaddr_r_8, [
	AC_TRY_COMPILE([
	    #include <netdb.h>
	], [
	    char *addr;
	    int length;
	    int type;
	    struct hostent *result, *resultp;
	    char buffer[2048];
	    int buflen = 2048;
	    int h_errnop;

	    (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen,
				   &resultp, &h_errnop);
	], tcl_cv_api_gethostbyaddr_r_8=yes, tcl_cv_api_gethostbyaddr_r_8=no)])
	tcl_ok=$tcl_cv_api_gethostbyaddr_r_8
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETHOSTBYADDR_R_8, 1,
		[Define to 1 if gethostbyaddr_r takes 8 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYADDR_R, 1,
	    [Define to 1 if gethostbyaddr_r is available.])
    fi
])])

#--------------------------------------------------------------------
# SC_TCL_GETHOSTBYNAME_R
#
#	Check to see what variant of gethostbyname_r() we have.
#	Based on David Arnold's example from the comp.programming.threads
#	FAQ Q213
#
# Arguments:
#	None
#	
# Results:
#
#	Might define the following vars:
#		HAVE_GETHOSTBYADDR_R
#		HAVE_GETHOSTBYADDR_R_3
#		HAVE_GETHOSTBYADDR_R_5
#		HAVE_GETHOSTBYADDR_R_6
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETHOSTBYNAME_R], [AC_CHECK_FUNC(gethostbyname_r, [
    AC_CACHE_CHECK([for gethostbyname_r with 6 args], tcl_cv_api_gethostbyname_r_6, [
    AC_TRY_COMPILE([
	#include <netdb.h>
    ], [
	char *name;
	struct hostent *he, *res;
	char buffer[2048];
	int buflen = 2048;
	int h_errnop;

	(void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop);
    ], tcl_cv_api_gethostbyname_r_6=yes, tcl_cv_api_gethostbyname_r_6=no)])
    tcl_ok=$tcl_cv_api_gethostbyname_r_6
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYNAME_R_6, 1,
	    [Define to 1 if gethostbyname_r takes 6 args.])
    else
	AC_CACHE_CHECK([for gethostbyname_r with 5 args], tcl_cv_api_gethostbyname_r_5, [
	AC_TRY_COMPILE([
	    #include <netdb.h>
	], [
	    char *name;
	    struct hostent *he;
	    char buffer[2048];
	    int buflen = 2048;
	    int h_errnop;

	    (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop);
	], tcl_cv_api_gethostbyname_r_5=yes, tcl_cv_api_gethostbyname_r_5=no)])
	tcl_ok=$tcl_cv_api_gethostbyname_r_5
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETHOSTBYNAME_R_5, 1,
		[Define to 1 if gethostbyname_r takes 5 args.])
	else
	    AC_CACHE_CHECK([for gethostbyname_r with 3 args], tcl_cv_api_gethostbyname_r_3, [
	    AC_TRY_COMPILE([
		#include <netdb.h>
	    ], [
		char *name;
		struct hostent *he;
		struct hostent_data data;

		(void) gethostbyname_r(name, he, &data);
	    ], tcl_cv_api_gethostbyname_r_3=yes, tcl_cv_api_gethostbyname_r_3=no)])
	    tcl_ok=$tcl_cv_api_gethostbyname_r_3
	    if test "$tcl_ok" = yes; then
		AC_DEFINE(HAVE_GETHOSTBYNAME_R_3, 1,
		    [Define to 1 if gethostbyname_r takes 3 args.])
	    fi
	fi
    fi
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYNAME_R, 1,
	    [Define to 1 if gethostbyname_r is available.])
    fi
])])

#--------------------------------------------------------------------
# SC_TCL_GETPWUID_R
#
#	Check if we have MT-safe variant of getpwuid() and if yes,
#	which one exactly.
#
# Arguments:
#	None
#	
# Results:
#
#	Might define the following vars:
#		HAVE_GETPWUID_R
#		HAVE_GETPWUID_R_4
#		HAVE_GETPWUID_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETPWUID_R], [AC_CHECK_FUNC(getpwuid_r, [
    AC_CACHE_CHECK([for getpwuid_r with 5 args], tcl_cv_api_getpwuid_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <pwd.h>
    ], [
	uid_t uid;
	struct passwd pw, *pwp;
	char buf[512];
	int buflen = 512;

	(void) getpwuid_r(uid, &pw, buf, buflen, &pwp);
    ], tcl_cv_api_getpwuid_r_5=yes, tcl_cv_api_getpwuid_r_5=no)])
    tcl_ok=$tcl_cv_api_getpwuid_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWUID_R_5, 1,
	    [Define to 1 if getpwuid_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getpwuid_r with 4 args], tcl_cv_api_getpwuid_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <pwd.h>
	], [
	    uid_t uid;
	    struct passwd pw;
	    char buf[512];
	    int buflen = 512;

	    (void)getpwnam_r(uid, &pw, buf, buflen);
	], tcl_cv_api_getpwuid_r_4=yes, tcl_cv_api_getpwuid_r_4=no)])
	tcl_ok=$tcl_cv_api_getpwuid_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETPWUID_R_4, 1,
		[Define to 1 if getpwuid_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWUID_R, 1,
	    [Define to 1 if getpwuid_r is available.])
    fi
])])

#--------------------------------------------------------------------
# SC_TCL_GETPWNAM_R
#
#	Check if we have MT-safe variant of getpwnam() and if yes,
#	which one exactly.
#
# Arguments:
#	None
#	
# Results:
#
#	Might define the following vars:
#		HAVE_GETPWNAM_R
#		HAVE_GETPWNAM_R_4
#		HAVE_GETPWNAM_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETPWNAM_R], [AC_CHECK_FUNC(getpwnam_r, [
    AC_CACHE_CHECK([for getpwnam_r with 5 args], tcl_cv_api_getpwnam_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <pwd.h>
    ], [
	char *name;
	struct passwd pw, *pwp;
	char buf[512];
	int buflen = 512;

	(void) getpwnam_r(name, &pw, buf, buflen, &pwp);
    ], tcl_cv_api_getpwnam_r_5=yes, tcl_cv_api_getpwnam_r_5=no)])
    tcl_ok=$tcl_cv_api_getpwnam_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWNAM_R_5, 1,
	    [Define to 1 if getpwnam_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getpwnam_r with 4 args], tcl_cv_api_getpwnam_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <pwd.h>
	], [
	    char *name;
	    struct passwd pw;
	    char buf[512];
	    int buflen = 512;

	    (void)getpwnam_r(name, &pw, buf, buflen);
	], tcl_cv_api_getpwnam_r_4=yes, tcl_cv_api_getpwnam_r_4=no)])
	tcl_ok=$tcl_cv_api_getpwnam_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETPWNAM_R_4, 1,
		[Define to 1 if getpwnam_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWNAM_R, 1,
	    [Define to 1 if getpwnam_r is available.])
    fi
])])

#--------------------------------------------------------------------
# SC_TCL_GETGRGID_R
#
#	Check if we have MT-safe variant of getgrgid() and if yes,
#	which one exactly.
#
# Arguments:
#	None
#	
# Results:
#
#	Might define the following vars:
#		HAVE_GETGRGID_R
#		HAVE_GETGRGID_R_4
#		HAVE_GETGRGID_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETGRGID_R], [AC_CHECK_FUNC(getgrgid_r, [
    AC_CACHE_CHECK([for getgrgid_r with 5 args], tcl_cv_api_getgrgid_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <grp.h>
    ], [
	gid_t gid;
	struct group gr, *grp;
	char buf[512];
	int buflen = 512;

	(void) getgrgid_r(gid, &gr, buf, buflen, &grp);
    ], tcl_cv_api_getgrgid_r_5=yes, tcl_cv_api_getgrgid_r_5=no)])
    tcl_ok=$tcl_cv_api_getgrgid_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRGID_R_5, 1,
	    [Define to 1 if getgrgid_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getgrgid_r with 4 args], tcl_cv_api_getgrgid_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <grp.h>
	], [
	    gid_t gid;
	    struct group gr;
	    char buf[512];
	    int buflen = 512;

	    (void)getgrgid_r(gid, &gr, buf, buflen);
	], tcl_cv_api_getgrgid_r_4=yes, tcl_cv_api_getgrgid_r_4=no)])
	tcl_ok=$tcl_cv_api_getgrgid_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETGRGID_R_4, 1,
		[Define to 1 if getgrgid_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRGID_R, 1,
	    [Define to 1 if getgrgid_r is available.])
    fi
])])

#--------------------------------------------------------------------
# SC_TCL_GETGRNAM_R
#
#	Check if we have MT-safe variant of getgrnam() and if yes,
#	which one exactly.
#
# Arguments:
#	None
#	
# Results:
#
#	Might define the following vars:
#		HAVE_GETGRNAM_R
#		HAVE_GETGRNAM_R_4
#		HAVE_GETGRNAM_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETGRNAM_R], [AC_CHECK_FUNC(getgrnam_r, [
    AC_CACHE_CHECK([for getgrnam_r with 5 args], tcl_cv_api_getgrnam_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <grp.h>
    ], [
	char *name;
	struct group gr, *grp;
	char buf[512];
	int buflen = 512;

	(void) getgrnam_r(name, &gr, buf, buflen, &grp);
    ], tcl_cv_api_getgrnam_r_5=yes, tcl_cv_api_getgrnam_r_5=no)])
    tcl_ok=$tcl_cv_api_getgrnam_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRNAM_R_5, 1,
	    [Define to 1 if getgrnam_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getgrnam_r with 4 args], tcl_cv_api_getgrnam_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <grp.h>
	], [
	    char *name;
	    struct group gr;
	    char buf[512];
	    int buflen = 512;

	    (void)getgrnam_r(name, &gr, buf, buflen);
	], tcl_cv_api_getgrnam_r_4=yes, tcl_cv_api_getgrnam_r_4=no)])
	tcl_ok=$tcl_cv_api_getgrnam_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETGRNAM_R_4, 1,
		[Define to 1 if getgrnam_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRNAM_R, 1,
	    [Define to 1 if getgrnam_r is available.])
    fi
])])

# Local Variables:
# mode: autoconf
# End:
href='#n7075'>7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612 8613 8614 8615 8616 8617 8618 8619 8620 8621 8622 8623 8624 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649 8650 8651 8652 8653 8654 8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875 8876 8877 8878 8879 8880 8881 8882 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976 8977 8978 8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 9115 9116 9117 9118 9119 9120 9121 9122 9123 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 9507 9508 9509 9510 9511 9512 9513 9514 9515 9516 9517 9518 9519 9520 9521 9522 9523 9524 9525 9526 9527 9528 9529 9530 9531 9532 9533 9534 9535 9536 9537 9538 9539 9540 9541 9542 9543 9544 9545 9546 9547 9548 9549 9550 9551 9552 9553 9554 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by the Board of Trustees of the University of Illinois.         *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
 * terms governing use, modification, and redistribution, is contained in    *
 * the files COPYING and Copyright.html.  COPYING can be found at the root   *
 * of the source code distribution tree; Copyright.html can be found at the  *
 * root level of an installed copy of the electronic HDF5 document set and   *
 * is linked from the top-level documents page.  It can also be found at     *
 * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html.  If you do not have     *
 * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/*
 * Module Info:	Data type conversions for the H5T interface.
 */

#define H5T_PACKAGE		/*suppress error about including H5Tpkg	     */

/* Pablo information */
/* (Put before include files to avoid problems with inline functions) */
#define PABLO_MASK    H5T_conv_mask

#include "H5private.h"		/*generic functions			  */
#include "H5Eprivate.h"		/*error handling			  */
#include "H5FLprivate.h"	/*Free Lists	                          */
#include "H5Iprivate.h"		/*ID functions		   		  */
#include "H5MMprivate.h"	/*memory management			  */
#include "H5Pprivate.h"		/* Property Lists			  */
#include "H5Dprivate.h"		/* Dataset 		                  */
#include "H5Tpkg.h"		/*data-type functions			  */

/* Conversion data for H5T_conv_struct() */
typedef struct H5T_conv_struct_t {
    int	*src2dst;		/*mapping from src to dst member num */
    hid_t	*src_memb_id;		/*source member type ID's	     */
    hid_t	*dst_memb_id;		/*destination member type ID's	     */
    H5T_path_t	**memb_path;		/*conversion path for each member    */
} H5T_conv_struct_t;

/* Conversion data for H5T_conv_enum() */
typedef struct H5T_enum_struct_t {
    int	base;			/*lowest `in' value		     */
    int	length;			/*num elements in arrays	     */
    int	*src2dst;		/*map from src to dst index	     */
} H5T_enum_struct_t;

/* Conversion data for the hardware conversion functions */
typedef struct H5T_conv_hw_t {
    size_t	s_aligned;		/*number source elements aligned     */
    size_t	d_aligned;		/*number destination elements aligned*/
} H5T_conv_hw_t;

/* Declare a free list to manage pieces of vlen data */
H5FL_BLK_DEFINE_STATIC(vlen_seq);

/* Declare a free list to manage pieces of array data */
H5FL_BLK_DEFINE_STATIC(array_seq);

/*
 * These macros are for the bodies of functions that convert buffers of one
 * atomic type to another using hardware.
 *
 * They all start with `H5T_CONV_' and end with two letters that represent the
 * source and destination types, respectively. The letters `s' and `S' refer to
 * signed integers while the letters `u' and `U' refer to unsigned integers, and
 * the letters `f' and `F' refer to floating-point values.
 *
 * The letter which is capitalized indicates that the corresponding type
 * (source or destination) is at least as large as the other type.
 *
 * Certain conversions may experience overflow conditions which arise when the
 * source value has a magnitude that cannot be represented by the destination
 * type.
 *
 * Suffix	Description
 * ------	-----------
 * sS:		Signed integers to signed integers where the destination is
 *		at least as wide as the source.	 This case cannot generate
 *		overflows.
 *
 * sU:		Signed integers to unsigned integers where the destination is
 *		at least as wide as the source.	 This case experiences
 *		overflows when the source value is negative.
 *
 * uS:		Unsigned integers to signed integers where the destination is
 *		at least as wide as the source.	 This case can experience
 *		overflows when the source and destination are the same size.
 *
 * uU:		Unsigned integers to unsigned integers where the destination
 *		is at least as wide as the source.  Overflows are not
 *		possible in this case.
 *
 * Ss:		Signed integers to signed integers where the source is at
 *		least as large as the destination.  Overflows can occur when
 *		the destination is narrower than the source.
 *
 * Su:		Signed integers to unsigned integers where the source is at
 *		least as large as the destination.  Overflows occur when the
 *		source value is negative and can also occur if the
 *		destination is narrower than the source.
 *
 * Us:		Unsigned integers to signed integers where the source is at
 *		least as large as the destination.  Overflows can occur for
 *		all sizes.
 *
 * Uu:		Unsigned integers to unsigned integers where the source is at
 *		least as large as the destination. Overflows can occur if the
 *		destination is narrower than the source.
 *
 * su:		Conversion from signed integers to unsigned integers where
 *		the source and destination are the same size. Overflow occurs
 *		when the source value is negative.
 *
 * us:		Conversion from unsigned integers to signed integers where
 *		the source and destination are the same size.  Overflow
 *		occurs when the source magnitude is too large for the
 *		destination.
 *
 * fF:		Floating-point values to floating-point values where the
 *              destination is at least as wide as the source.	 This case
 *              cannot generate overflows.
 *
 * Ff:		Floating-point values to floating-point values the source is at
 *		least as large as the destination.  Overflows can occur when
 *		the destination is narrower than the source.
 *
 * xF:          Integers to float-point values where the desination is
 *              at least as wide as the source.  This case cannot generate 
 *              overflows.
 *
 * Fx:          Float-point values to integer where the source is
 *              at least as wide as the destination.  Overflow can occur 
 *              when the source magnitude is too large for the destination.
 *              
 * The macros take a subset of these arguments in the order listed here:
 *
 * CDATA:	A pointer to the H5T_cdata_t structure that was passed to the
 *		conversion function.
 *
 * STYPE:	The hid_t value for the source data type.
 *
 * DTYPE:	The hid_t value for the destination data type.
 *
 * BUF:		A pointer to the conversion buffer.
 *
 * NELMTS:	The number of values to be converted.
 *
 * ST:		The C name for source data type (e.g., int)
 *
 * DT:		The C name for the destination data type (e.g., signed char)
 *
 * D_MIN:	The minimum possible destination value.	 For unsigned
 *		destination types this should be zero.	For signed
 *		destination types it's a negative value with a magnitude that
 *		is usually one greater than D_MAX.  Source values which are
 *		smaller than D_MIN generate overflows.
 *
 * D_MAX:	The maximum possible destination value. Source values which
 *		are larger than D_MAX generate overflows.
 * 
 * The macros are implemented with a generic programming technique, similar
 * to templates in C++.  The macro which defines the "core" part of the
 * conversion (which actually moves the data from the source to the destination)
 * is invoked inside the H5T_CONV "template" macro by "gluing" it together,
 * which allows the core conversion macro to be invoked as necessary.
 * 
 * The generic "core" macros are: (others are specific to particular conversion)
 * 
 * Suffix	Description
 * ------	-----------
 * xX:		Generic Conversion where the destination is at least as
 *              wide as the source.  This case cannot generate overflows.
 *
 * Xx:		Generic signed conversion where the source is at least as large
 *              as the destination.  Overflows can occur when the destination is
 *              narrower than the source.
 *
 * Ux:		Generic conversion for the `Us', `Uu' & `us' cases
 *		Overflow occurs when the source magnitude is too large for the
 *		destination.
 *
 */
#define H5T_CONV_xX_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {		      \
    *((DT*)D) = (DT)(*((ST*)S));					      \
}

#define H5T_CONV_Xx_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {		      \
    if (*((ST*)S) > (DT)(D_MAX)) {					      \
        if(cb_struct.func) { /*If user's exception handler is present, use it*/ \
            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI,           \
                    src_id, dst_id, S, D, cb_struct.user_data);               \
        }                                                                     \
                                                                              \
        if(except_ret == H5T_CONV_UNHANDLED) {                                \
            /*let compiler convert if case is ignored by user handler*/       \
            *((DT*)D) = (D_MAX);					      \
        } else if(except_ret == H5T_CONV_ABORT)                               \
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
    } else if (*((ST*)S) < (D_MIN)) {					      \
        if(cb_struct.func) { /*If user's exception handler is present, use it*/ \
            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW,          \
                    src_id, dst_id, S, D, cb_struct.user_data);               \
        }                                                                     \
                                                                              \
        if(except_ret == H5T_CONV_UNHANDLED) {                                \
            /*let compiler convert if case is ignored by user handler*/       \
            *((DT*)D) = (D_MIN);					      \
        } else if(except_ret == H5T_CONV_ABORT)                               \
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
    } else								      \
        *((DT*)D) = (DT)(*((ST*)S));					      \
}                                                                               

#define H5T_CONV_Ux_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {		      \
    if (*((ST*)S) > (D_MAX)) {						      \
        if(cb_struct.func) { /*If user's exception handler is present, use it*/ \
            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI,           \
                    src_id, dst_id, S, D, cb_struct.user_data);               \
        }                                                                     \
                                                                              \
        if(except_ret == H5T_CONV_UNHANDLED) {                                \
            /*let compiler convert if case is ignored by user handler*/       \
            *((DT*)D) = (D_MAX);					      \
        } else if(except_ret == H5T_CONV_ABORT)                               \
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
    } else								      \
        *((DT*)D) = (DT)(*((ST*)S));					      \
}

#define H5T_CONV_sS(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)<=sizeof(DT));					      \
    H5T_CONV(H5T_CONV_xX, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)      \
}

#define H5T_CONV_sU_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {		      \
    if (*((ST*)S)<0) {							      \
        if(cb_struct.func) { /*If user's exception handler is present, use it*/ \
            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW,          \
                    src_id, dst_id, S, D, cb_struct.user_data);               \
        }                                                                     \
                                                                              \
        if(except_ret == H5T_CONV_UNHANDLED) {                                \
            /*let compiler convert if case is ignored by user handler*/       \
            *((DT*)D) = 0;                                                    \
        } else if(except_ret == H5T_CONV_ABORT)                               \
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
    } else								      \
        *((DT*)D) = (DT)(*((ST*)S));					      \
}

#define H5T_CONV_sU(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)<=sizeof(DT));					      \
    H5T_CONV(H5T_CONV_sU, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)      \
}

#define H5T_CONV_uS_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {		      \
    if (sizeof(ST)==sizeof(DT) && *((ST*)S) > (D_MAX)) {		      \
        if(cb_struct.func) { /*If user's exception handler is present, use it*/ \
            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI,           \
                    src_id, dst_id, S, D, cb_struct.user_data);               \
        }                                                                     \
                                                                              \
        if(except_ret == H5T_CONV_UNHANDLED) {                                \
            /*let compiler convert if case is ignored by user handler*/       \
            *((DT*)D) = (D_MAX);					      \
        } else if(except_ret == H5T_CONV_ABORT)                               \
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
    } else								      \
        *((DT*)D) = (DT)(*((ST*)S));					      \
}

#define H5T_CONV_uS(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)<=sizeof(DT));					      \
    H5T_CONV(H5T_CONV_uS, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)      \
}

#define H5T_CONV_uU(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)<=sizeof(DT));					      \
    H5T_CONV(H5T_CONV_xX, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)      \
}

#define H5T_CONV_Ss(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)>=sizeof(DT));					      \
    H5T_CONV(H5T_CONV_Xx, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)      \
}

#define H5T_CONV_Su_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {		      \
    if (*((ST*)S) < 0) {						      \
        if(cb_struct.func) { /*If user's exception handler is present, use it*/ \
            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW,          \
                    src_id, dst_id, S, D, cb_struct.user_data);               \
        }                                                                     \
                                                                              \
        if(except_ret == H5T_CONV_UNHANDLED) {                                \
            /*let compiler convert if case is ignored by user handler*/       \
            *((DT*)D) = 0;                                                    \
        } else if(except_ret == H5T_CONV_ABORT)                               \
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
    } else if (sizeof(ST)>sizeof(DT) && *((ST*)S)>(ST)(D_MAX)) {	      \
        /*sign vs. unsign ok in previous line*/				      \
        if(cb_struct.func) { /*If user's exception handler is present, use it*/ \
            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI,           \
                    src_id, dst_id, S, D, cb_struct.user_data);               \
        }                                                                     \
                                                                              \
        if(except_ret == H5T_CONV_UNHANDLED) {                                \
            /*let compiler convert if case is ignored by user handler*/       \
            *((DT*)D) = (D_MAX);					      \
        } else if(except_ret == H5T_CONV_ABORT)                               \
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
    } else								      \
        *((DT*)D) = (DT)(*((ST*)S));					      \
}

#define H5T_CONV_Su(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)>=sizeof(DT));					      \
    H5T_CONV(H5T_CONV_Su, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)      \
}

#define H5T_CONV_Us(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)>=sizeof(DT));					      \
    H5T_CONV(H5T_CONV_Ux, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)      \
}

#define H5T_CONV_Uu(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)>=sizeof(DT));					      \
    H5T_CONV(H5T_CONV_Ux, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)      \
}

#define H5T_CONV_su_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {		      \
    /* Assumes memory format of unsigned & signed integers is same */	      \
    if (*((ST*)S)<0) {							      \
        if(cb_struct.func) { /*If user's exception handler is present, use it*/ \
            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW,          \
                    src_id, dst_id, S, D, cb_struct.user_data);               \
        }                                                                     \
                                                                              \
        if(except_ret == H5T_CONV_UNHANDLED) {                                \
            /*let compiler convert if case is ignored by user handler*/       \
            *((DT*)D) = 0;                                                    \
        } else if(except_ret == H5T_CONV_ABORT)                               \
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
    }									      \
}

#define H5T_CONV_su(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)==sizeof(DT));					      \
    H5T_CONV(H5T_CONV_su, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)      \
}

#define H5T_CONV_us_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {		      \
    /* Assumes memory format of unsigned & signed integers is same */	      \
    if (*((ST*)S) > (D_MAX)) {						      \
        if(cb_struct.func) { /*If user's exception handler is present, use it*/ \
            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI,           \
                    src_id, dst_id, S, D, cb_struct.user_data);               \
        }                                                                     \
                                                                              \
        if(except_ret == H5T_CONV_UNHANDLED) {                                \
            /*let compiler convert if case is ignored by user handler*/       \
            *((DT*)D) = (D_MAX);					      \
        } else if(except_ret == H5T_CONV_ABORT)                               \
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
    }									      \
}

#define H5T_CONV_us(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)==sizeof(DT));					      \
    H5T_CONV(H5T_CONV_us, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)      \
}

#define H5T_CONV_fF(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)<=sizeof(DT));					      \
    H5T_CONV(H5T_CONV_xX, double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)	      \
}

/* Same as H5T_CONV_Xx_CORE, except that instead of using D_MAX and D_MIN
 * when an overflow occurs, use the 'float' infinity values.
 */
#define H5T_CONV_Ff_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {		      \
    if (*((ST*)S) > (DT)(D_MAX)) {					      \
        if(cb_struct.func) { /*If user's exception handler is present, use it*/ \
            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI,           \
                    src_id, dst_id, S, D, cb_struct.user_data);               \
        }                                                                     \
                                                                              \
        if(except_ret == H5T_CONV_UNHANDLED) {                                \
            /*let compiler convert if case is ignored by user handler*/       \
            *((DT*)D) = (H5T_NATIVE_FLOAT_POS_INF_g);			      \
        } else if(except_ret == H5T_CONV_ABORT)                               \
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
    } else if (*((ST*)S) < (D_MIN)) {					      \
        if(cb_struct.func) { /*If user's exception handler is present, use it*/ \
            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW,          \
                    src_id, dst_id, S, D, cb_struct.user_data);               \
        }                                                                     \
                                                                              \
        if(except_ret == H5T_CONV_UNHANDLED) {                                \
            /*let compiler convert if case is ignored by user handler*/       \
            *((DT*)D) = (H5T_NATIVE_FLOAT_NEG_INF_g);			      \
        } else if(except_ret == H5T_CONV_ABORT)                               \
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
    } else								      \
        *((DT*)D) = (DT)(*((ST*)S));					      \
}

#define H5T_CONV_Ff(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    assert(sizeof(ST)>=sizeof(DT));					      \
    H5T_CONV(H5T_CONV_Ff, double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)	      \
}

#define H5T_CONV_xF(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    H5T_CONV(H5T_CONV_xX, double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)	      \
}

#define H5T_CONV_Fx(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {			      \
    H5T_CONV(H5T_CONV_Xx, double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX)	      \
}

/* The main part of every integer hardware conversion macro */
#define H5T_CONV(GUTS,ATYPE,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) {		      \
    size_t	elmtno;			/*element number		*/    \
    uint8_t	*src, *s;		/*source buffer			*/    \
    uint8_t	*dst, *d;		/*destination buffer		*/    \
    H5T_t	*st, *dt;		/*data type descriptors		*/    \
    ATYPE	aligned;		/*aligned type			*/    \
    hbool_t	s_mv, d_mv;		/*move data to align it?	*/    \
    ssize_t	s_stride, d_stride;	/*src and dst strides		*/    \
    size_t      safe;                   /*how many elements are safe to process in each pass */ \
    H5P_genplist_t      *plist;         /*Property list pointer         */    \
    H5T_conv_cb_t       cb_struct;      /*conversion callback structure */    \
    H5T_conv_ret_t      except_ret;     /*callback return*/                   \
                                                                              \
    switch (cdata->command) {						      \
    case H5T_CONV_INIT:							      \
	/* Sanity check and initialize statistics */			      \
	cdata->need_bkg = H5T_BKG_NO;					      \
	if (NULL==(st=H5I_object(src_id)) || NULL==(dt=H5I_object(dst_id)))   \
	    HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,		      \
			  "unable to dereference datatype object ID")	      \
	if (st->shared->size!=sizeof(ST) || dt->shared->size!=sizeof(DT))		      \
	    HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,		      \
			  "disagreement about datatype size")		      \
	CI_ALLOC_PRIV	                                                      \
	break;								      \
									      \
    case H5T_CONV_FREE:							      \
	/* Print and free statistics */					      \
	CI_PRINT_STATS(STYPE,DTYPE);					      \
	CI_FREE_PRIV	                                                      \
	break;								      \
									      \
    case H5T_CONV_CONV:							      \
	/* Initialize source & destination strides */			      \
	if (buf_stride) {						      \
            assert(buf_stride>=sizeof(ST));				      \
            assert(buf_stride>=sizeof(DT));				      \
	    s_stride = d_stride = buf_stride;				      \
	} else {							      \
            s_stride = sizeof(ST);					      \
            d_stride = sizeof(DT);					      \
        }								      \
									      \
	/* Is alignment required for source or dest? */			      \
	s_mv = H5T_NATIVE_##STYPE##_ALIGN_g>1 &&			      \
               ((size_t)buf%H5T_NATIVE_##STYPE##_ALIGN_g ||		      \
     /* Cray */ ((size_t)((ST*)buf)!=(size_t)buf) ||			      \
		s_stride%H5T_NATIVE_##STYPE##_ALIGN_g);			      \
	d_mv = H5T_NATIVE_##DTYPE##_ALIGN_g>1 &&			      \
               ((size_t)buf%H5T_NATIVE_##DTYPE##_ALIGN_g ||		      \
     /* Cray */ ((size_t)((DT*)buf)!=(size_t)buf) ||			      \
                d_stride%H5T_NATIVE_##DTYPE##_ALIGN_g);			      \
	CI_INC_SRC(s_mv)						      \
	CI_INC_DST(d_mv)						      \
	                                                                      \
        /* Get the plist structure */                                         \
        if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))     \
            HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); \
                                                                              \
        /* Get conversion exception callback property */                      \
        if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0)                \
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); \
                                                                              \
        /* The outer loop of the type conversion macro, controlling which */  \
        /* direction the buffer is walked */				      \
        while (nelmts>0) {						      \
            /* Check if we need to go backwards through the buffer */	      \
            if(d_stride>s_stride) {					      \
                /* Compute the number of "safe" destination elements at */    \
                /* the end of the buffer (Those which don't overlap with */   \
                /* any source elements at the beginning of the buffer) */     \
                safe=nelmts-(((nelmts*s_stride)+(d_stride-1))/d_stride);      \
									      \
                /* If we're down to the last few elements, just wrap up */    \
                /* with a "real" reverse copy */			      \
                if(safe<2) {						      \
                    src = (uint8_t*)buf+(nelmts-1)*s_stride;		      \
                    dst = (uint8_t*)buf+(nelmts-1)*d_stride;		      \
                    s_stride = -s_stride;				      \
                    d_stride = -d_stride;				      \
									      \
                    safe=nelmts;					      \
                } /* end if */						      \
                else {							      \
                    src = (uint8_t*)buf+(nelmts-safe)*s_stride;		      \
                    dst = (uint8_t*)buf+(nelmts-safe)*d_stride;		      \
                } /* end else */					      \
            } /* end if */						      \
            else {							      \
                /* Single forward pass over all data */			      \
                src = dst = buf;					      \
                safe=nelmts;						      \
            } /* end else */						      \
                                                                              \
	    except_ret = H5T_CONV_UNHANDLED; 			              \
                                                                              \
            /* Perform loop over elements to convert */			      \
            if (s_mv && d_mv) {						      \
                /* Alignment is required for both source and dest */	      \
                s = (uint8_t*)&aligned;					      \
                H5T_CONV_LOOP(PRE_SALIGN,PRE_DALIGN,POST_SALIGN,POST_DALIGN,GUTS,s,d,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
            } else if(s_mv) {						      \
                /* Alignment is required only for source */		      \
                s = (uint8_t*)&aligned;					      \
                H5T_CONV_LOOP(PRE_SALIGN,PRE_DNOALIGN,POST_SALIGN,POST_DNOALIGN,GUTS,s,dst,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
            } else if(d_mv) {						      \
                /* Alignment is required only for destination */	      \
                H5T_CONV_LOOP(PRE_SNOALIGN,PRE_DALIGN,POST_SNOALIGN,POST_DALIGN,GUTS,src,d,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
            } else {							      \
                /* Alignment is not required for both source and destination */ \
                H5T_CONV_LOOP(PRE_SNOALIGN,PRE_DNOALIGN,POST_SNOALIGN,POST_DNOALIGN,GUTS,src,dst,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
            }	 	 	 	 	 	 	 	      \
									      \
            /* Decrement number of elements left to convert */		      \
            nelmts-=safe;						      \
        } /* end while */						      \
        break;								      \
									      \
    default:								      \
	HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,		      \
		      "unknown conversion command");			      \
    }									      \
}

/* Macro defining action on source data which needs to be aligned (before main action) */
#define H5T_CONV_LOOP_PRE_SALIGN(ST) {					      \
    HDmemcpy(&aligned, src, sizeof(ST));				      \
}

/* Macro defining action on source data which doesn't need to be aligned (before main action) */
#define H5T_CONV_LOOP_PRE_SNOALIGN(ST) {				      \
}

/* Macro defining action on destination data which needs to be aligned (before main action) */
#define H5T_CONV_LOOP_PRE_DALIGN(DT) {					      \
    d = (uint8_t*)&aligned;						      \
}

/* Macro defining action on destination data which doesn't need to be aligned (before main action) */
#define H5T_CONV_LOOP_PRE_DNOALIGN(DT) {				      \
}

/* Macro defining action on source data which needs to be aligned (after main action) */
#define H5T_CONV_LOOP_POST_SALIGN(ST) {					      \
}

/* Macro defining action on source data which doesn't need to be aligned (after main action) */
#define H5T_CONV_LOOP_POST_SNOALIGN(ST) {				      \
}

/* Macro defining action on destination data which needs to be aligned (after main action) */
#define H5T_CONV_LOOP_POST_DALIGN(DT) {					      \
    HDmemcpy(dst, &aligned, sizeof(DT));				      \
}

/* Macro defining action on destination data which doesn't need to be aligned (after main action) */
#define H5T_CONV_LOOP_POST_DNOALIGN(DT) {				      \
}

/* The inner loop of the type conversion macro, actually converting the elements */
#define H5T_CONV_LOOP(PRE_SALIGN_GUTS,PRE_DALIGN_GUTS,POST_SALIGN_GUTS,POST_DALIGN_GUTS,GUTS,S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
    for (elmtno=0; elmtno<safe; elmtno++) {				      \
        /* Handle source pre-alignment */				      \
        H5_GLUE(H5T_CONV_LOOP_,PRE_SALIGN_GUTS)(ST)			      \
									      \
        /* Handle destination pre-alignment */				      \
        H5_GLUE(H5T_CONV_LOOP_,PRE_DALIGN_GUTS)(DT)			      \
									      \
        /* ... user-defined stuff here -- the conversion ... */		      \
        H5_GLUE(GUTS,_CORE)(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX)		      \
									      \
        /* Handle source post-alignment */				      \
        H5_GLUE(H5T_CONV_LOOP_,POST_SALIGN_GUTS)(ST)			      \
									      \
        /* Handle destination post-alignment */				      \
        H5_GLUE(H5T_CONV_LOOP_,POST_DALIGN_GUTS)(DT)			      \
									      \
        /* Advance pointers */						      \
        src += s_stride;						      \
        dst += d_stride;						      \
    }


#ifdef H5T_DEBUG

/* Print alignment statistics */
#   define CI_PRINT_STATS(STYPE,DTYPE) {				      \
    if (H5DEBUG(T) && ((H5T_conv_hw_t *)cdata->priv)->s_aligned) {				      \
	HDfprintf(H5DEBUG(T),						      \
		  "      %Hu src elements aligned on %lu-byte boundaries\n",  \
		  ((H5T_conv_hw_t *)cdata->priv)->s_aligned,				\
		  (unsigned long)H5T_NATIVE_##STYPE##_ALIGN_g);		      \
    }									      \
    if (H5DEBUG(T) && ((H5T_conv_hw_t *)cdata->priv)->d_aligned) {				      \
	HDfprintf(H5DEBUG(T),						      \
		  "      %Hu dst elements aligned on %lu-byte boundaries\n",  \
		  ((H5T_conv_hw_t *)cdata->priv)->d_aligned,				\
		  (unsigned long)H5T_NATIVE_##DTYPE##_ALIGN_g);		      \
    }									      \
}

/* Allocate private alignment structure for atomic types */
#   define CI_ALLOC_PRIV \
	if (NULL==(cdata->priv=H5MM_calloc(sizeof(H5T_conv_hw_t)))) {	      \
	    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,		      \
			  "memory allocation failed");			      \
	}

/* Free private alignment structure for atomic types */
#   define CI_FREE_PRIV                                 \
    if(cdata->priv!=NULL)                               \
        cdata->priv = H5MM_xfree(cdata->priv);

/* Increment source alignment counter */
#   define CI_INC_SRC(s)   if (s) ((H5T_conv_hw_t *)cdata->priv)->s_aligned += nelmts;

/* Increment destination alignment counter */
#   define CI_INC_DST(d)   if (d) ((H5T_conv_hw_t *)cdata->priv)->d_aligned += nelmts;
#else /* H5T_DEBUG */
#   define CI_PRINT_STATS(STYPE,DTYPE) /*void*/
#   define CI_ALLOC_PRIV cdata->priv=NULL;
#   define CI_FREE_PRIV  /* void */
#   define CI_INC_SRC(s) /* void */
#   define CI_INC_DST(d) /* void */
#endif /* H5T_DEBUG */

/* Swap two elements (I & J) of an array using a temporary variable */
#define H5_SWAP_BYTES(ARRAY,I,J) {uint8_t _tmp; _tmp=ARRAY[I]; ARRAY[I]=ARRAY[J]; ARRAY[J]=_tmp;}

/* Minimum size of variable-length conversion buffer */
#define H5T_VLEN_MIN_CONF_BUF_SIZE      4096

static herr_t H5T_reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order);


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_noop
 *
 * Purpose:	The no-op conversion.  The library knows about this
 *		conversion without it being registered.
 *
 * Return: 	Non-negative on success/Negative on failure
 *
 * Programmer:	Robb Matzke
 *		Wednesday, January 14, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_noop(hid_t UNUSED src_id, hid_t UNUSED dst_id, H5T_cdata_t *cdata,
	      size_t UNUSED nelmts, size_t UNUSED buf_stride,
              size_t UNUSED bkg_stride, void UNUSED *buf,
	      void UNUSED *background, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_noop, FAIL);

    switch (cdata->command) {
        case H5T_CONV_INIT:
            cdata->need_bkg = H5T_BKG_NO;
            break;

        case H5T_CONV_CONV:
            /* Nothing to convert */
            break;

        case H5T_CONV_FREE:
            break;
        
        default:
            HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
    }

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_order_opt
 *
 * Purpose:	Convert one type to another when byte order is the only
 *		difference. This is the optimized version of H5T_conv_order()
 *              for a handful of different sizes.
 *
 * Note:	This is a soft conversion function.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Robb Matzke
 *		Friday, January 25, 2002
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
                   size_t nelmts, size_t buf_stride,
                   size_t UNUSED bkg_stride, void *_buf,
                   void UNUSED *background, hid_t UNUSED dxpl_id)
{
    uint8_t	*buf = (uint8_t*)_buf;
    H5T_t	*src = NULL;
    H5T_t	*dst = NULL;
    size_t      i;
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_order_opt, FAIL);

    switch (cdata->command) {
    case H5T_CONV_INIT:
	/* Capability query */
	if (NULL == (src = H5I_object(src_id)) ||
                NULL == (dst = H5I_object(dst_id)))
	    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
	if (src->shared->size != dst->shared->size ||
                0 != src->shared->u.atomic.offset ||
                0 != dst->shared->u.atomic.offset)
	    HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
        if((src->shared->type==H5T_REFERENCE && dst->shared->type!=H5T_REFERENCE) ||
                (dst->shared->type==H5T_REFERENCE && src->shared->type!=H5T_REFERENCE))
	    HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
        if(src->shared->type!=H5T_REFERENCE &&
                !((H5T_ORDER_BE == src->shared->u.atomic.order && H5T_ORDER_LE == dst->shared->u.atomic.order) ||
                  (H5T_ORDER_LE == src->shared->u.atomic.order && H5T_ORDER_BE == dst->shared->u.atomic.order)))
	    HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
        if (src->shared->size!=1 && src->shared->size!=2 && src->shared->size!=4 &&
                src->shared->size!=8 && src->shared->size!=16)
            HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
	switch (src->shared->type) {
            case H5T_INTEGER:
            case H5T_BITFIELD:
            case H5T_REFERENCE:
                /* nothing to check */
                break;

            case H5T_FLOAT:
                if (src->shared->u.atomic.u.f.sign != dst->shared->u.atomic.u.f.sign ||
                        src->shared->u.atomic.u.f.epos != dst->shared->u.atomic.u.f.epos ||
                        src->shared->u.atomic.u.f.esize != dst->shared->u.atomic.u.f.esize ||
                        src->shared->u.atomic.u.f.ebias != dst->shared->u.atomic.u.f.ebias ||
                        src->shared->u.atomic.u.f.mpos != dst->shared->u.atomic.u.f.mpos ||
                        src->shared->u.atomic.u.f.msize != dst->shared->u.atomic.u.f.msize ||
                        src->shared->u.atomic.u.f.norm != dst->shared->u.atomic.u.f.norm ||
                        src->shared->u.atomic.u.f.pad != dst->shared->u.atomic.u.f.pad)
                    HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
                break;

            default:
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
	}
	cdata->need_bkg = H5T_BKG_NO;
	break;

    case H5T_CONV_CONV:
	/* The conversion */
	if (NULL == (src = H5I_object(src_id)) ||
                NULL == (dst = H5I_object(dst_id)))
	    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");

        /* Check for "no op" reference conversion */
        if(src->shared->type==H5T_REFERENCE) {
            /* Sanity check */
            assert(dst->shared->type==H5T_REFERENCE);

            /* Check if we are on a little-endian machine (the order that
             * the addresses in the file must be) and just get out now, there
             * is no need to convert the object reference.  Yes, this is
             * icky and non-portable, but I can't think of a better way to
             * support allowing the objno in the H5G_stat_t struct and the
             * hobj_ref_t type to be compared directly without introducing a
             * "native" hobj_ref_t datatype and I think that would break a
             * lot of existing programs.  -QAK
             */
            if(H5T_native_order_g == H5T_ORDER_LE)
                break;
        } /* end if */

        buf_stride = buf_stride ? buf_stride : src->shared->size;
        switch (src->shared->size) {
        case 1:
            /*no-op*/
            break;
        case 2:
            for (/*void*/; nelmts>=20; nelmts-=20) {
                H5_SWAP_BYTES(buf, 0,   1); /*  0 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /*  1 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /*  2 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /*  3 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /*  4 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /*  5 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /*  6 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /*  7 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /*  8 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /*  9 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /* 10 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /* 11 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /* 12 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /* 13 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /* 14 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /* 15 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /* 16 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /* 17 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /* 18 */
                buf += buf_stride; 
                H5_SWAP_BYTES(buf, 0,   1); /* 19 */
                buf += buf_stride;
            }
            for (i=0; i<nelmts; i++, buf+=buf_stride) {
                H5_SWAP_BYTES(buf, 0, 1);
            }
            break;
        case 4:
            for (/*void*/; nelmts>=20; nelmts-=20) {
                H5_SWAP_BYTES(buf,  0,  3); /*  0 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /*  1 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /*  2 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /*  3 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /*  4 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /*  5 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /*  6 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /*  7 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /*  8 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /*  9 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /* 10 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /* 11 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /* 12 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /* 13 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /* 14 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /* 15 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /* 16 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /* 17 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /* 18 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  3); /* 19 */
                H5_SWAP_BYTES(buf,  1,  2);
                buf += buf_stride;
            }
            for (i=0; i<nelmts; i++, buf+=buf_stride) {
                H5_SWAP_BYTES(buf, 0, 3);
                H5_SWAP_BYTES(buf, 1, 2);
            }
            break;
        case 8:
            for (/*void*/; nelmts>=10; nelmts-=10) {
                H5_SWAP_BYTES(buf,  0,  7); /*  0 */
                H5_SWAP_BYTES(buf,  1,  6);
                H5_SWAP_BYTES(buf,  2,  5);
                H5_SWAP_BYTES(buf,  3,  4);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  7); /*  1 */
                H5_SWAP_BYTES(buf,  1,  6);
                H5_SWAP_BYTES(buf,  2,  5);
                H5_SWAP_BYTES(buf,  3,  4);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  7); /*  2 */
                H5_SWAP_BYTES(buf,  1,  6);
                H5_SWAP_BYTES(buf,  2,  5);
                H5_SWAP_BYTES(buf,  3,  4);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  7); /*  3 */
                H5_SWAP_BYTES(buf,  1,  6);
                H5_SWAP_BYTES(buf,  2,  5);
                H5_SWAP_BYTES(buf,  3,  4);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  7); /*  4 */
                H5_SWAP_BYTES(buf,  1,  6);
                H5_SWAP_BYTES(buf,  2,  5);
                H5_SWAP_BYTES(buf,  3,  4);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  7); /*  5 */
                H5_SWAP_BYTES(buf,  1,  6);
                H5_SWAP_BYTES(buf,  2,  5);
                H5_SWAP_BYTES(buf,  3,  4);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  7); /*  6 */
                H5_SWAP_BYTES(buf,  1,  6);
                H5_SWAP_BYTES(buf,  2,  5);
                H5_SWAP_BYTES(buf,  3,  4);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  7); /*  7 */
                H5_SWAP_BYTES(buf,  1,  6);
                H5_SWAP_BYTES(buf,  2,  5);
                H5_SWAP_BYTES(buf,  3,  4);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  7); /*  8 */
                H5_SWAP_BYTES(buf,  1,  6);
                H5_SWAP_BYTES(buf,  2,  5);
                H5_SWAP_BYTES(buf,  3,  4);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,  0,  7); /*  9 */
                H5_SWAP_BYTES(buf,  1,  6);
                H5_SWAP_BYTES(buf,  2,  5);
                H5_SWAP_BYTES(buf,  3,  4);
                buf += buf_stride;
            }
            for (i=0; i<nelmts; i++, buf+=buf_stride) {
                H5_SWAP_BYTES(buf, 0, 7);
                H5_SWAP_BYTES(buf, 1, 6);
                H5_SWAP_BYTES(buf, 2, 5);
                H5_SWAP_BYTES(buf, 3, 4);
            }
            break;
        case 16:
            for (/*void*/; nelmts>=10; nelmts-=10) {
                H5_SWAP_BYTES(buf,   0,  15); /*  0 */
                H5_SWAP_BYTES(buf,   1,  14);
                H5_SWAP_BYTES(buf,   2,  13);
                H5_SWAP_BYTES(buf,   3,  12);
                H5_SWAP_BYTES(buf,   4,  11);
                H5_SWAP_BYTES(buf,   5,  10);
                H5_SWAP_BYTES(buf,   6,   9);
                H5_SWAP_BYTES(buf,   7,   8);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,   0,  15); /*  1 */
                H5_SWAP_BYTES(buf,   1,  14);
                H5_SWAP_BYTES(buf,   2,  13);
                H5_SWAP_BYTES(buf,   3,  12);
                H5_SWAP_BYTES(buf,   4,  11);
                H5_SWAP_BYTES(buf,   5,  10);
                H5_SWAP_BYTES(buf,   6,   9);
                H5_SWAP_BYTES(buf,   7,   8);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,   0,  15); /*  2 */
                H5_SWAP_BYTES(buf,   1,  14);
                H5_SWAP_BYTES(buf,   2,  13);
                H5_SWAP_BYTES(buf,   3,  12);
                H5_SWAP_BYTES(buf,   4,  11);
                H5_SWAP_BYTES(buf,   5,  10);
                H5_SWAP_BYTES(buf,   6,   9);
                H5_SWAP_BYTES(buf,   7,   8);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,   0,  15); /*  3 */
                H5_SWAP_BYTES(buf,   1,  14);
                H5_SWAP_BYTES(buf,   2,  13);
                H5_SWAP_BYTES(buf,   3,  12);
                H5_SWAP_BYTES(buf,   4,  11);
                H5_SWAP_BYTES(buf,   5,  10);
                H5_SWAP_BYTES(buf,   6,   9);
                H5_SWAP_BYTES(buf,   7,   8);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,   0,  15); /*  4 */
                H5_SWAP_BYTES(buf,   1,  14);
                H5_SWAP_BYTES(buf,   2,  13);
                H5_SWAP_BYTES(buf,   3,  12);
                H5_SWAP_BYTES(buf,   4,  11);
                H5_SWAP_BYTES(buf,   5,  10);
                H5_SWAP_BYTES(buf,   6,   9);
                H5_SWAP_BYTES(buf,   7,   8);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,   0,  15); /*  5 */
                H5_SWAP_BYTES(buf,   1,  14);
                H5_SWAP_BYTES(buf,   2,  13);
                H5_SWAP_BYTES(buf,   3,  12);
                H5_SWAP_BYTES(buf,   4,  11);
                H5_SWAP_BYTES(buf,   5,  10);
                H5_SWAP_BYTES(buf,   6,   9);
                H5_SWAP_BYTES(buf,   7,   8);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,   0,  15); /*  6 */
                H5_SWAP_BYTES(buf,   1,  14);
                H5_SWAP_BYTES(buf,   2,  13);
                H5_SWAP_BYTES(buf,   3,  12);
                H5_SWAP_BYTES(buf,   4,  11);
                H5_SWAP_BYTES(buf,   5,  10);
                H5_SWAP_BYTES(buf,   6,   9);
                H5_SWAP_BYTES(buf,   7,   8);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,   0,  15); /*  7 */
                H5_SWAP_BYTES(buf,   1,  14);
                H5_SWAP_BYTES(buf,   2,  13);
                H5_SWAP_BYTES(buf,   3,  12);
                H5_SWAP_BYTES(buf,   4,  11);
                H5_SWAP_BYTES(buf,   5,  10);
                H5_SWAP_BYTES(buf,   6,   9);
                H5_SWAP_BYTES(buf,   7,   8);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,   0,  15); /*  8 */
                H5_SWAP_BYTES(buf,   1,  14);
                H5_SWAP_BYTES(buf,   2,  13);
                H5_SWAP_BYTES(buf,   3,  12);
                H5_SWAP_BYTES(buf,   4,  11);
                H5_SWAP_BYTES(buf,   5,  10);
                H5_SWAP_BYTES(buf,   6,   9);
                H5_SWAP_BYTES(buf,   7,   8);
                buf += buf_stride;
                H5_SWAP_BYTES(buf,   0,  15); /*  9 */
                H5_SWAP_BYTES(buf,   1,  14);
                H5_SWAP_BYTES(buf,   2,  13);
                H5_SWAP_BYTES(buf,   3,  12);
                H5_SWAP_BYTES(buf,   4,  11);
                H5_SWAP_BYTES(buf,   5,  10);
                H5_SWAP_BYTES(buf,   6,   9);
                H5_SWAP_BYTES(buf,   7,   8);
                buf += buf_stride;
            }
            for (i=0; i<nelmts; i++, buf+=buf_stride) {
                H5_SWAP_BYTES(buf, 0, 15);
                H5_SWAP_BYTES(buf, 1, 14);
                H5_SWAP_BYTES(buf, 2, 13);
                H5_SWAP_BYTES(buf, 3, 12);
                H5_SWAP_BYTES(buf, 4, 11);
                H5_SWAP_BYTES(buf, 5, 10);
                H5_SWAP_BYTES(buf, 6,  9);
                H5_SWAP_BYTES(buf, 7,  8);
            }
            break;
        }
        break;

    case H5T_CONV_FREE:
	/* Free private data */
	break;

    default:
	HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
    }

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_order
 *
 * Purpose:	Convert one type to another when byte order is the only
 *		difference.
 *
 * Note:	This is a soft conversion function.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Robb Matzke
 *		Tuesday, January 13, 1998
 *
 * Modifications:
 *		Robb Matzke, 1999-06-16
 *		Added the `stride' argument. If its value is non-zero then we
 *		stride through memory converting one value at each location;
 *		otherwise we assume that the values should be packed.
 *
 * 		Robb Matzke, 1999-06-16
 *		Added support for bitfields.
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
	       size_t buf_stride, size_t UNUSED bkg_stride, void *_buf,
               void UNUSED *background, hid_t UNUSED dxpl_id)
{
    uint8_t	*buf = (uint8_t*)_buf;
    H5T_t	*src = NULL;
    H5T_t	*dst = NULL;
    size_t	i;
    size_t	j, md;
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_order, FAIL);

    switch (cdata->command) {
    case H5T_CONV_INIT:
	/* Capability query */
	if (NULL == (src = H5I_object(src_id)) ||
                NULL == (dst = H5I_object(dst_id)))
	    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
	if (src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset ||
                0 != dst->shared->u.atomic.offset ||
                !((H5T_ORDER_BE == src->shared->u.atomic.order &&
                   H5T_ORDER_LE == dst->shared->u.atomic.order) ||
                  (H5T_ORDER_LE == src->shared->u.atomic.order &&
                   H5T_ORDER_BE == dst->shared->u.atomic.order)))
	    HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
	switch (src->shared->type) {
            case H5T_INTEGER:
            case H5T_BITFIELD:
                /* nothing to check */
                break;

            case H5T_FLOAT:
                if (src->shared->u.atomic.u.f.sign != dst->shared->u.atomic.u.f.sign ||
                        src->shared->u.atomic.u.f.epos != dst->shared->u.atomic.u.f.epos ||
                        src->shared->u.atomic.u.f.esize != dst->shared->u.atomic.u.f.esize ||
                        src->shared->u.atomic.u.f.ebias != dst->shared->u.atomic.u.f.ebias ||
                        src->shared->u.atomic.u.f.mpos != dst->shared->u.atomic.u.f.mpos ||
                        src->shared->u.atomic.u.f.msize != dst->shared->u.atomic.u.f.msize ||
                        src->shared->u.atomic.u.f.norm != dst->shared->u.atomic.u.f.norm ||
                        src->shared->u.atomic.u.f.pad != dst->shared->u.atomic.u.f.pad) {
                    HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
                }
                break;

            default:
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
	}
	cdata->need_bkg = H5T_BKG_NO;
	break;

    case H5T_CONV_CONV:
	/* The conversion */
	if (NULL == (src = H5I_object(src_id)) ||
                NULL == (dst = H5I_object(dst_id)))
	    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");

        buf_stride = buf_stride ? buf_stride : src->shared->size;
        md = src->shared->size / 2;
        for (i=0; i<nelmts; i++, buf+=buf_stride) {
            for (j=0; j<md; j++)
                H5_SWAP_BYTES(buf, j, src->shared->size-(j+1));
        }
        break;

    case H5T_CONV_FREE:
	/* Free private data */
	break;

    default:
	HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
    }

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_b_b
 *
 * Purpose:	Convert from one bitfield to any other bitfield.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Robb Matzke
 *		Thursday, May 20, 1999
 *
 * Modifications:
 *		Robb Matzke, 1999-06-16
 *		Added support for non-zero strides. If BUF_STRIDE is non-zero
 *		then convert one value at each memory location advancing
 *		BUF_STRIDE bytes each time; otherwise assume both source and
 *		destination values are packed.
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
	     size_t buf_stride, size_t UNUSED bkg_stride, void *_buf,
             void UNUSED *background, hid_t dxpl_id)
{
    uint8_t	*buf = (uint8_t*)_buf;
    H5T_t	*src=NULL, *dst=NULL;	/*source and dest data types	*/
    int	direction;		/*direction of traversal	*/
    size_t	elmtno;			/*element number		*/
    size_t	olap;			/*num overlapping elements	*/
    size_t	half_size;		/*1/2 of total size for swapping*/
    uint8_t	*s, *sp, *d, *dp;	/*source and dest traversal ptrs*/
    uint8_t	dbuf[256];		/*temp destination buffer	*/
    size_t	msb_pad_offset;		/*offset for dest MSB padding	*/
    size_t	i;
    uint8_t     *src_rev;               /*order-reversed source buffer  */
    H5P_genplist_t      *plist;         /*property list pointer         */
    H5T_conv_cb_t       cb_struct={NULL, NULL};      /*conversion callback structure */
    H5T_conv_ret_t      except_ret;     /*return of callback function   */
    hbool_t             reverse;        /*if reverse the order of destination        */
    herr_t      ret_value=SUCCEED;      /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_b_b, FAIL);

    switch(cdata->command) {
        case H5T_CONV_INIT:
            /* Capability query */
            if (NULL == (src = H5I_object(src_id)) ||
                    NULL == (dst = H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            if (H5T_ORDER_LE!=src->shared->u.atomic.order &&
                    H5T_ORDER_BE!=src->shared->u.atomic.order)
                HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
            if (H5T_ORDER_LE!=dst->shared->u.atomic.order &&
                    H5T_ORDER_BE!=dst->shared->u.atomic.order)
                HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
            cdata->need_bkg = H5T_BKG_NO;
            break;

        case H5T_CONV_FREE:
            break;

        case H5T_CONV_CONV:
            /* Get the data types */
            if (NULL==(src=H5I_object(src_id)) ||
                    NULL==(dst=H5I_object(dst_id)))
                HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");

            /*
             * Do we process the values from beginning to end or vice versa? Also,
             * how many of the elements have the source and destination areas
             * overlapping?
             */
            if (src->shared->size==dst->shared->size || buf_stride) {
                sp = dp = (uint8_t*)buf;
                direction = 1;
                olap = nelmts;
            } else if (src->shared->size>=dst->shared->size) {
                double olap_d = HDceil((double)(dst->shared->size)/
                                       (double)(src->shared->size-dst->shared->size));
                
                olap = (size_t)olap_d;
                sp = dp = (uint8_t*)buf;
                direction = 1;
            } else {
                double olap_d = HDceil((double)(src->shared->size)/
                                       (double)(dst->shared->size-src->shared->size));
                olap = (size_t)olap_d;
                sp = (uint8_t*)buf + (nelmts-1) * src->shared->size;
                dp = (uint8_t*)buf + (nelmts-1) * dst->shared->size;
                direction = -1;
            }

            /* Get the plist structure */
            if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
                HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID");

            /* Get conversion exception callback property */
            if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0)
                HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback");

            /* Allocate space for order-reversed source buffer */
            src_rev = (uint8_t*)H5MM_calloc(src->shared->size);
            
            /* The conversion loop */
            for (elmtno=0; elmtno<nelmts; elmtno++) {

                /*
                 * If the source and destination buffers overlap then use a
                 * temporary buffer for the destination.
                 */
                if (direction>0) {
                    s = sp;
                    d = elmtno<olap ? dbuf : dp;
                } else {
                    s = sp;
                    d = elmtno+olap >= nelmts ? dbuf : dp;
                }
#ifndef NDEBUG
                /* I don't quite trust the overlap calculations yet --rpm */
                if (d==dbuf) {
                    assert ((dp>=sp && dp<sp+src->shared->size) ||
                            (sp>=dp && sp<dp+dst->shared->size));
                } else {
                    assert ((dp<sp && dp+dst->shared->size<=sp) ||
                            (sp<dp && sp+src->shared->size<=dp));
                }
#endif
                
                /*
                 * Put the data in little endian order so our loops aren't so
                 * complicated.  We'll do all the conversion stuff assuming
                 * little endian and then we'll fix the order at the end.
                 */
                if (H5T_ORDER_BE==src->shared->u.atomic.order) {
                    half_size = src->shared->size/2;
                    for (i=0; i<half_size; i++) {
                        uint8_t tmp = s[src->shared->size-(i+1)];
                        s[src->shared->size-(i+1)] = s[i];
                        s[i] = tmp;
                    }
                }

                /* Initiate these variables */
                except_ret = H5T_CONV_UNHANDLED;
                reverse    = TRUE;

                /*
                 * Copy the significant part of the value. If the source is larger
                 * than the destination then invoke the overflow function or copy
                 * as many bits as possible. Zero extra bits in the destination.
                 */
                if (src->shared->u.atomic.prec>dst->shared->u.atomic.prec) {
                    /*overflow*/
                    if(cb_struct.func) { /*If user's exception handler is present, use it*/
                        H5T_reverse_order(src_rev, s, src->shared->size, src->shared->u.atomic.order); /*reverse order first*/
                        except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, 
                                src_rev, d, cb_struct.user_data);
                    }
                    
                    if(except_ret == H5T_CONV_UNHANDLED) { 
                        H5T_bit_copy(d, dst->shared->u.atomic.offset,
                                     s, src->shared->u.atomic.offset, dst->shared->u.atomic.prec);
                    } else if(except_ret == H5T_CONV_ABORT)
                        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception")
                    else if(except_ret == H5T_CONV_HANDLED)
                        /*Don't reverse because user handles it*/
                        reverse = FALSE;
                } else {
                    H5T_bit_copy(d, dst->shared->u.atomic.offset,
                                 s, src->shared->u.atomic.offset,
                                 src->shared->u.atomic.prec);
                    H5T_bit_set(d, dst->shared->u.atomic.offset+src->shared->u.atomic.prec,
                                dst->shared->u.atomic.prec-src->shared->u.atomic.prec, FALSE);
                }

                /*
                 * Fill the destination padding areas.
                 */
                switch (dst->shared->u.atomic.lsb_pad) {
                    case H5T_PAD_ZERO:
                        H5T_bit_set(d, 0, dst->shared->u.atomic.offset, FALSE);
                        break;
                    case H5T_PAD_ONE:
                        H5T_bit_set(d, 0, dst->shared->u.atomic.offset, TRUE);
                        break;
                    default:
                        HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported LSB padding");
                }
                msb_pad_offset = dst->shared->u.atomic.offset + dst->shared->u.atomic.prec;
                switch (dst->shared->u.atomic.msb_pad) {
                    case H5T_PAD_ZERO:
                        H5T_bit_set(d, msb_pad_offset, 8*dst->shared->size-msb_pad_offset,
                                    FALSE);
                        break;
                    case H5T_PAD_ONE:
                        H5T_bit_set(d, msb_pad_offset, 8*dst->shared->size-msb_pad_offset,
                                    TRUE);
                        break;
                    default:
                        HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported MSB padding");
                }

                /*
                 * Put the destination in the correct byte order.  See note at
                 * beginning of loop.
                 */
                if (H5T_ORDER_BE==dst->shared->u.atomic.order && reverse) {
                    half_size = dst->shared->size/2;
                    for (i=0; i<half_size; i++) {
                        uint8_t tmp = d[dst->shared->size-(i+1)];
                        d[dst->shared->size-(i+1)] = d[i];
                        d[i] = tmp;
                    }
                }

                /*
                 * If we had used a temporary buffer for the destination then we
                 * should copy the value to the true destination buffer.
                 */
                if (d==dbuf) HDmemcpy (dp, d, dst->shared->size);
                if (buf_stride) {
                    sp += direction * buf_stride;
                    dp += direction * buf_stride;
                } else {
                    sp += direction * src->shared->size;
                    dp += direction * dst->shared->size;
                }
            }
            
            H5MM_free(src_rev);

            break;

        default:
            HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
    }

done:
    FUNC_LEAVE_NOAPI(ret_value);
}
	    

/*-------------------------------------------------------------------------
 * Function:	H5T_conv_struct_init
 *
 * Purpose:	Initialize the `priv' field of `cdata' with conversion
 *		information that is relatively constant.  If `priv' is
 *		already initialized then the member conversion functions
 *		are recalculated.
 *
 *		Priv fields are indexed by source member number or
 *		destination member number depending on whether the field
 *		contains information about the source data type or the
 *		destination data type (fields that contains the same
 *		information for both source and destination are indexed by
 *		source member number).  The src2dst[] priv array maps source
 *		member numbers to destination member numbers, but if the
 *		source member doesn't have a corresponding destination member
 *		then the src2dst[i]=-1.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Robb Matzke
 *		Monday, January 26, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id)
{
    H5T_conv_struct_t	*priv = (H5T_conv_struct_t*)(cdata->priv);
    int		*src2dst = NULL;
    unsigned		i, j;
    H5T_t		*type = NULL;
    hid_t		tid;
    herr_t      ret_value=SUCCEED;       /* Return value */
    
    FUNC_ENTER_NOAPI_NOINIT(H5T_conv_struct_init);
    
    if (!priv) {
        /*
         * Allocate private data structure and arrays.
         */
        if (NULL==(priv=cdata->priv=H5MM_calloc(sizeof(H5T_conv_struct_t))) ||
                NULL==(priv->src2dst=H5MM_malloc(src->shared->u.compnd.nmembs *
                                 sizeof(int))) ||
                NULL==(priv->src_memb_id=H5MM_malloc(src->shared->u.compnd.nmembs *
                                    sizeof(hid_t))) ||
                NULL==(priv->dst_memb_id=H5MM_malloc(dst->shared->u.compnd.nmembs *
                                    sizeof(hid_t))))
            HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
        src2dst = priv->src2dst;

        /*
         * Insure that members are sorted.
         */
        H5T_sort_value(src, NULL);
        H5T_sort_value(dst, NULL);

        /*
         * Build a mapping from source member number to destination member
         * number. If some source member is not a destination member then that
         * mapping element will be negative.  Also create atoms for each
         * source and destination member data type so we can look up the
         * member data type conversion functions later.
         */
        for (i=0; i<src->shared->u.compnd.nmembs; i++) {
            src2dst[i] = -1;
            for (j=0; j<dst->shared->u.compnd.nmembs; j++) {
                if (!HDstrcmp (src->shared->u.compnd.memb[i].name,
                       dst->shared->u.compnd.memb[j].name)) {
                    src2dst[i] = j;
                    break;
                }
            }
            if (src2dst[i]>=0) {
                type = H5T_copy (src->shared->u.compnd.memb[i].type, H5T_COPY_ALL);
                tid = H5I_register (H5I_DATATYPE, type);
                assert (tid>=0);
                priv->src_memb_id[i] = tid;

                type = H5T_copy (dst->shared->u.compnd.memb[src2dst[i]].type,
                     H5T_COPY_ALL);
                tid = H5I_register (H5I_DATATYPE, type);
                assert (tid>=0);
                priv->dst_memb_id[src2dst[i]] = tid;
            }
        }
    }
    else {
        /* Restore sorted conditions for the datatypes */
        /* (Required for the src2dst array to be valid) */
        H5T_sort_value(src, NULL);
        H5T_sort_value(dst, NULL);
    } /* end else */

    /*
     * (Re)build the cache of member conversion functions and pointers to
     * their cdata entries.
     */
    src2dst = priv->src2dst;
    H5MM_xfree(priv->memb_path);
    if (NULL==(priv->memb_path=H5MM_malloc(src->shared->u.compnd.nmembs *
					   sizeof(H5T_path_t*))))
        HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");

    for (i=0; i<src->shared->u.compnd.nmembs; i++) {
        if (src2dst[i]>=0) {
            H5T_path_t *tpath = H5T_path_find(src->shared->u.compnd.memb[i].type,
                      dst->shared->u.compnd.memb[src2dst[i]].type, NULL, NULL, dxpl_id);

            if (NULL==(priv->memb_path[i] = tpath)) {
                H5MM_xfree(priv->src2dst);
                H5MM_xfree(priv->src_memb_id);
                H5MM_xfree(priv->dst_memb_id);
                H5MM_xfree(priv->memb_path);
                cdata->priv = priv = H5MM_xfree (priv);
                HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member data type");
            }
        }
    }

    /* Check if we need a background buffer */
    if (H5T_detect_class(src,H5T_COMPOUND)==TRUE || H5T_detect_class(dst,H5T_COMPOUND)==TRUE)
        cdata->need_bkg = H5T_BKG_YES;

    cdata->recalc = FALSE;

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*------------------------------------------------------------------------- 
 * Function:	H5T_conv_struct
 *
 * Purpose:	Converts between compound data types.  This is a soft
 *		conversion function.  The algorithm is basically:
 *
 * 		For each element do
 *		  For I=1..NELMTS do
 *		    If sizeof detination type <= sizeof source type then
 *		      Convert member to destination type;
 *		    Move member as far left as possible;
 *		  
 *		  For I=NELMTS..1 do
 *		    If not destination type then
 *		      Convert member to destination type;
 *		    Move member to correct position in BKG
 *
 *		  Copy BKG to BUF
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Robb Matzke
 *		Thursday, January 22, 1998
 *
 * Modifications:
 *		Robb Matzke, 1999-06-16
 *              Added support for non-zero strides. If BUF_STRIDE is
 *              non-zero then convert one value at each memory location
 *              advancing BUF_STRIDE bytes each time; otherwise assume
 *              both source and destination values are packed.
 *
 *              Robb Matzke, 2000-05-17
 *              Added the BKG_STRIDE argument to fix a design bug. If
 *              BUF_STRIDE and BKG_STRIDE are both non-zero then each
 *              data element converted will be placed temporarily at a
 *              multiple of BKG_STRIDE in the BKG buffer; otherwise the
 *              BKG buffer is assumed to be a packed array of destination
 *              datatype.
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
		size_t buf_stride, size_t bkg_stride, void *_buf, void *_bkg,
                hid_t dxpl_id)
{
    uint8_t	*buf = (uint8_t *)_buf;	/*cast for pointer arithmetic	*/
    uint8_t	*bkg = (uint8_t *)_bkg;	/*background pointer arithmetic	*/
    uint8_t     *xbuf=buf, *xbkg=bkg;   /*temp pointers into buf and bkg*/
    H5T_t	*src = NULL;		/*source data type		*/
    H5T_t	*dst = NULL;		/*destination data type		*/
    int	*src2dst = NULL;	/*maps src member to dst member	*/
    H5T_cmemb_t	*src_memb = NULL;	/*source struct member descript.*/
    H5T_cmemb_t	*dst_memb = NULL;	/*destination struct memb desc.	*/
    size_t	offset;			/*byte offset wrt struct	*/
    size_t	src_delta;	    /*source stride	*/
    size_t	elmtno;
    unsigned	u;		/*counters			*/
    int	i;			/*counters			*/
    H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv);
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_struct, FAIL);

    switch (cdata->command) {
        case H5T_CONV_INIT:
            /*
             * First, determine if this conversion function applies to the
             * conversion path SRC_ID-->DST_ID.  If not, return failure;
             * otherwise initialize the `priv' field of `cdata' with information
             * that remains (almost) constant for this conversion path.
             */
            if (NULL == (src = H5I_object(src_id)) ||
                    NULL == (dst = H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            assert (H5T_COMPOUND==src->shared->type);
            assert (H5T_COMPOUND==dst->shared->type);

            if (H5T_conv_struct_init (src, dst, cdata, dxpl_id)<0)
                HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data");
            break;

        case H5T_CONV_FREE:
            /*
             * Free the private conversion data.
             */
            H5MM_xfree(priv->src2dst);
            H5MM_xfree(priv->src_memb_id);
            H5MM_xfree(priv->dst_memb_id);
            H5MM_xfree(priv->memb_path);
            cdata->priv = priv = H5MM_xfree (priv);
            break;

        case H5T_CONV_CONV:
            /*
             * Conversion.
             */
            if (NULL == (src = H5I_object(src_id)) ||
                    NULL == (dst = H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            assert (priv);
            assert (bkg && cdata->need_bkg);

            if (cdata->recalc && H5T_conv_struct_init (src, dst, cdata, dxpl_id)<0)
                HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data");

            /*
             * Insure that members are sorted.
             */
            H5T_sort_value(src, NULL);
            H5T_sort_value(dst, NULL);
            src2dst = priv->src2dst;

            /*
             * Direction of conversion and striding through background.
             */
            if (buf_stride) {
                src_delta = buf_stride;
            if (!bkg_stride)
                bkg_stride = dst->shared->size;
            } else if (dst->shared->size <= src->shared->size) {
                src_delta = src->shared->size;
            bkg_stride = dst->shared->size;
            } else {
                src_delta = -(int)src->shared->size; /*overflow shouldn't be possible*/
                bkg_stride = -(int)dst->shared->size; /*overflow shouldn't be possible*/
                xbuf += (nelmts-1) * src->shared->size;
                xbkg += (nelmts-1) * dst->shared->size;
            }

            /* Conversion loop... */
            for (elmtno=0; elmtno<nelmts; elmtno++) {
                /*
                 * For each source member which will be present in the
                 * destination, convert the member to the destination type unless
                 * it is larger than the source type.  Then move the member to the
                 * left-most unoccupied position in the buffer.  This makes the
                 * data point as small as possible with all the free space on the
                 * right side.
                 */
                for (u=0, offset=0; u<src->shared->u.compnd.nmembs; u++) {
                    if (src2dst[u]<0) continue; /*subsetting*/
                    src_memb = src->shared->u.compnd.memb + u;
                    dst_memb = dst->shared->u.compnd.memb + src2dst[u];

                    if (dst_memb->size <= src_memb->size) {
                        if (H5T_convert(priv->memb_path[u], priv->src_memb_id[u],
                                priv->dst_memb_id[src2dst[u]],
                                1, 0, 0, /*no striding (packed array)*/
                                xbuf+src_memb->offset, xbkg+dst_memb->offset,
                                dxpl_id)<0)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member");
                        HDmemmove (xbuf+offset, xbuf+src_memb->offset,
                                   dst_memb->size);
                        offset += dst_memb->size;
                    } else {
                        HDmemmove (xbuf+offset, xbuf+src_memb->offset,
                                   src_memb->size);
                        offset += src_memb->size;
                    }
                }

                /*
                 * For each source member which will be present in the
                 * destination, convert the member to the destination type if it
                 * is larger than the source type (that is, has not been converted
                 * yet).  Then copy the member to the destination offset in the
                 * background buffer.
                 */
                for (i=src->shared->u.compnd.nmembs-1; i>=0; --i) {
                    if (src2dst[i]<0) continue; /*subsetting*/
                    src_memb = src->shared->u.compnd.memb + i;
                    dst_memb = dst->shared->u.compnd.memb + src2dst[i];

                    if (dst_memb->size > src_memb->size) {
                        offset -= src_memb->size;
                        if (H5T_convert(priv->memb_path[i],
                                    priv->src_memb_id[i], priv->dst_memb_id[src2dst[i]],
                                    1, 0, 0, /*no striding (packed array)*/
                                    xbuf+offset, xbkg+dst_memb->offset,
                                    dxpl_id)<0)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member");
                    } else {
                        offset -= dst_memb->size;
                    }
                    HDmemmove (xbkg+dst_memb->offset, xbuf+offset, dst_memb->size);
                }
                assert (0==offset);

                /*
                 * Update pointers
                 */
                xbuf += src_delta;
                xbkg += bkg_stride;
            }

        /* If the bkg_stride was set to -(dst->shared->size), make it positive now */
        if(buf_stride==0 && dst->shared->size>src->shared->size)
            bkg_stride=dst->shared->size;

            /*
             * Copy the background buffer back into the in-place conversion
             * buffer.
             */
            for (xbuf=buf, xbkg=bkg, elmtno=0; elmtno<nelmts; elmtno++) {
                HDmemmove(xbuf, xbkg, dst->shared->size);
                xbuf += buf_stride ? buf_stride : dst->shared->size;
                xbkg += bkg_stride;
            }
            break;

        default:
            /* Some other command we don't know about yet.*/
            HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
    }
    
done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_struct_opt
 *
 * Purpose:	Converts between compound data types in a manner more
 *		efficient than the general-purpose H5T_conv_struct()
 *		function.  This function isn't applicable if the destination
 *		is larger than the source type. This is a soft conversion
 *		function.  The algorithm is basically:
 *
 * 		For each member of the struct
 *		  If sizeof detination type <= sizeof source type then
 *		    Convert member to destination type for all elements
 *		    Move memb to BKG buffer for all elements
 *		  Else
 *		    Move member as far left as possible for all elements
 *		  
 *		For each member of the struct (in reverse order)
 *		  If not destination type then
 *		    Convert member to destination type for all elements
 *		    Move member to correct position in BKG for all elements
 *
 *		Copy BKG to BUF for all elements
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Robb Matzke
 *		Thursday, January 22, 1998
 *
 * Modifications:
 *		Robb Matzke, 1999-06-16
 *              Added support for non-zero strides. If BUF_STRIDE is
 *              non-zero then convert one value at each memory location
 *              advancing BUF_STRIDE bytes each time; otherwise assume both
 *              source and destination values are packed.
 *
 * 		Robb Matzke, 1999-06-16
 *		If the source and destination data structs are the same size
 *		then we can convert on a field-by-field basis instead of an
 *		element by element basis. In other words, for all struct
 *		elements being converted by this function call, first convert
 *		all of the field1's, then all field2's, etc. This can
 *		drastically reduce the number of calls to H5T_convert() and
 *		thereby eliminate most of the conversion constant overhead.
 *              
 *              Robb Matzke, 2000-05-17
 *              Added the BKG_STRIDE argument to fix a design bug. If
 *              BUF_STRIDE and BKG_STRIDE are both non-zero then each
 *              data element converted will be placed temporarily at a
 *              multiple of BKG_STRIDE in the BKG buffer; otherwise the
 *              BKG buffer is assumed to be a packed array of destination
 *              datatype.
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
    size_t nelmts, size_t buf_stride, size_t bkg_stride, void *_buf,
    void *_bkg, hid_t dxpl_id)
{
    uint8_t	*buf = (uint8_t *)_buf;	/*cast for pointer arithmetic	*/
    uint8_t	*bkg = (uint8_t *)_bkg;	/*background pointer arithmetic	*/
    uint8_t	*xbuf = NULL;		/*temporary pointer into `buf'	*/
    uint8_t	*xbkg = NULL;		/*temporary pointer into `bkg'	*/
    H5T_t	*src = NULL;		/*source data type		*/
    H5T_t	*dst = NULL;		/*destination data type		*/
    int	*src2dst = NULL;	/*maps src member to dst member	*/
    H5T_cmemb_t	*src_memb = NULL;	/*source struct member descript.*/
    H5T_cmemb_t	*dst_memb = NULL;	/*destination struct memb desc.	*/
    size_t	offset;			/*byte offset wrt struct	*/
    size_t	elmtno;			/*element counter		*/
    unsigned	u;			/*counters			*/
    int	i;			    /*counters			*/
    H5T_conv_struct_t *priv = NULL;	/*private data			*/
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_struct_opt, FAIL);

    switch (cdata->command) {
        case H5T_CONV_INIT:
            /*
             * First, determine if this conversion function applies to the
             * conversion path SRC_ID-->DST_ID.  If not, return failure;
             * otherwise initialize the `priv' field of `cdata' with information
             * that remains (almost) constant for this conversion path.
             */
            if (NULL == (src = H5I_object(src_id)) ||
                    NULL == (dst = H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            assert (H5T_COMPOUND==src->shared->type);
            assert (H5T_COMPOUND==dst->shared->type);

            /* Initialize data which is relatively constant */
            if (H5T_conv_struct_init (src, dst, cdata, dxpl_id)<0)
                HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data");
            priv = (H5T_conv_struct_t *)(cdata->priv);
            src2dst = priv->src2dst;
                
            /*
             * If the destination type is not larger than the source type then
             * this conversion function is guaranteed to work (provided all
             * members can be converted also). Otherwise the determination is
             * quite a bit more complicated. Essentially we have to make sure
             * that there is always room in the source buffer to do the
             * conversion of a member in place. This is basically the same pair
             * of loops as in the actual conversion except it checks that there
             * is room for each conversion instead of actually doing anything.
             */
            if (dst->shared->size > src->shared->size) {
                for (u=0, offset=0; u<src->shared->u.compnd.nmembs; u++) {
                    if (src2dst[u]<0)
                        continue;
                    src_memb = src->shared->u.compnd.memb + u;
                    dst_memb = dst->shared->u.compnd.memb + src2dst[u];
                    if (dst_memb->size > src_memb->size)
                        offset += src_memb->size;
                }
                for (i=src->shared->u.compnd.nmembs-1; i>=0; --i) {
                    if (src2dst[i]<0)
                        continue;
                    src_memb = src->shared->u.compnd.memb + i;
                    dst_memb = dst->shared->u.compnd.memb + src2dst[i];
                    if (dst_memb->size > src_memb->size) {
                        offset -= src_memb->size;
                        if (dst_memb->size > src->shared->size-offset) {
                            H5MM_xfree(priv->src2dst);
                            H5MM_xfree(priv->src_memb_id);
                            H5MM_xfree(priv->dst_memb_id);
                            H5MM_xfree(priv->memb_path);
                            cdata->priv = priv = H5MM_xfree (priv);
                            HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "convertion is unsupported by this function");
                        }
                    }
                }
            }
            break;

        case H5T_CONV_FREE:
            /*
             * Free the private conversion data.
             */
            priv = (H5T_conv_struct_t *)(cdata->priv);
            H5MM_xfree(priv->src2dst);
            H5MM_xfree(priv->src_memb_id);
            H5MM_xfree(priv->dst_memb_id);
            H5MM_xfree(priv->memb_path);
            cdata->priv = priv = H5MM_xfree (priv);
            break;

        case H5T_CONV_CONV:
            /*
             * Conversion.
             */
            if (NULL == (src = H5I_object(src_id)) ||
                    NULL == (dst = H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");

            /* Update cached data if necessary */
            if (cdata->recalc && H5T_conv_struct_init (src, dst, cdata, dxpl_id)<0)
                HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data");
            priv = (H5T_conv_struct_t *)(cdata->priv);
            src2dst = priv->src2dst;
            assert(priv);
            assert(bkg && cdata->need_bkg);

            /*
             * Insure that members are sorted.
             */
            H5T_sort_value(src, NULL);
            H5T_sort_value(dst, NULL);

            /* 
             * Calculate strides. If BUF_STRIDE is non-zero then convert one
             * data element at every BUF_STRIDE bytes through the main buffer
             * (BUF), leaving the result of each conversion at the same
             * location; otherwise assume the source and destination data are
             * packed tightly based on src->shared->size and dst->shared->size.  Also, if
             * BUF_STRIDE and BKG_STRIDE are both non-zero then place
             * background data into the BKG buffer at multiples of BKG_STRIDE;
             * otherwise assume BKG buffer is the packed destination datatype.
             */
            if (!buf_stride || !bkg_stride) bkg_stride = dst->shared->size;

            /*
             * For each member where the destination is not larger than the
             * source, stride through all the elements converting only that member
             * in each element and then copying the element to its final
             * destination in the bkg buffer. Otherwise move the element as far
             * left as possible in the buffer.
             */
            for (u=0, offset=0; u<src->shared->u.compnd.nmembs; u++) {
                if (src2dst[u]<0) continue; /*subsetting*/
                src_memb = src->shared->u.compnd.memb + u;
                dst_memb = dst->shared->u.compnd.memb + src2dst[u];

                if (dst_memb->size <= src_memb->size) {
                    xbuf = buf + src_memb->offset;
                    xbkg = bkg + dst_memb->offset;
                    if (H5T_convert(priv->memb_path[u],
                            priv->src_memb_id[u],
                            priv->dst_memb_id[src2dst[u]], nelmts,
                            buf_stride ? buf_stride : src->shared->size,
                            bkg_stride, xbuf, xbkg,
                            dxpl_id)<0)
                        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member");
                    for (elmtno=0; elmtno<nelmts; elmtno++) {
                        HDmemmove(xbkg, xbuf, dst_memb->size);
                        xbuf += buf_stride ? buf_stride : src->shared->size;
                        xbkg += bkg_stride;
                    }
                } else {
                    for (xbuf=buf, elmtno=0; elmtno<nelmts; elmtno++) {
                        HDmemmove(xbuf+offset, xbuf+src_memb->offset,
                                              src_memb->size);
                        xbuf += buf_stride ? buf_stride : src->shared->size;
                    }
                    offset += src_memb->size;
                }
            }

            /*
             * Work from right to left, converting those members that weren't
             * converted in the previous loop (those members where the destination
             * is larger than the source) and them to their final position in the
             * bkg buffer.
             */
            for (i=src->shared->u.compnd.nmembs-1; i>=0; --i) {
                if (src2dst[i]<0)
                    continue;
                src_memb = src->shared->u.compnd.memb + i;
                dst_memb = dst->shared->u.compnd.memb + src2dst[i];

                if (dst_memb->size > src_memb->size) {
                    offset -= src_memb->size;
                    xbuf = buf + offset;
                    xbkg = bkg + dst_memb->offset;
                    if (H5T_convert(priv->memb_path[i],
                                    priv->src_memb_id[i],
                                    priv->dst_memb_id[src2dst[i]], nelmts,
                                    buf_stride ? buf_stride : src->shared->size,
                                    bkg_stride, xbuf, xbkg,
                                    dxpl_id)<0)
                        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member");
                    for (elmtno=0; elmtno<nelmts; elmtno++) {
                        HDmemmove(xbkg, xbuf, dst_memb->size);
                        xbuf += buf_stride ? buf_stride : src->shared->size;
                        xbkg += bkg_stride;
                    }
                }
            }

            /* Move background buffer into result buffer */
            for (xbuf=buf, xbkg=bkg, elmtno=0; elmtno<nelmts; elmtno++) {
                HDmemmove(xbuf, xbkg, dst->shared->size);
                xbuf += buf_stride ? buf_stride : dst->shared->size;
                xbkg += bkg_stride;
            }
            break;

        default:
            /* Some other command we don't know about yet.*/
            HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
    }
    
done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_enum_init
 *
 * Purpose:	Initialize information for H5T_conv_enum().
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *              Monday, January  4, 1999
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
{
    H5T_enum_struct_t	*priv=NULL;	/*private conversion data	*/
    int		n;		/*src value cast as native int	*/
    int		domain[2];	/*min and max source values	*/
    int		*map=NULL;	/*map from src value to dst idx	*/
    unsigned	length;		/*nelmts in map array		*/
    unsigned	i, j;		/*counters			*/
    herr_t      ret_value=SUCCEED;       /* Return value */
    
    FUNC_ENTER_NOAPI_NOINIT(H5T_conv_enum_init);

    cdata->need_bkg = H5T_BKG_NO;
    if (NULL==(priv=cdata->priv=H5MM_calloc(sizeof(*priv))))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
    if (0==src->shared->u.enumer.nmembs)
	HGOTO_DONE(SUCCEED);

    /*
     * Check that the source symbol names are a subset of the destination
     * symbol names and build a map from source member index to destination
     * member index.
     */
    H5T_sort_name(src, NULL);
    H5T_sort_name(dst, NULL);
    if (NULL==(priv->src2dst=H5MM_malloc(src->shared->u.enumer.nmembs*sizeof(int))))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");;
    for (i=0, j=0;
             i<src->shared->u.enumer.nmembs && j<dst->shared->u.enumer.nmembs;
             i++, j++) {
	while (j<dst->shared->u.enumer.nmembs &&
	       HDstrcmp(src->shared->u.enumer.name[i], dst->shared->u.enumer.name[j]))
            j++;
	if (j>=dst->shared->u.enumer.nmembs)
	    HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "source type is not a subset of destination type");
	priv->src2dst[i] = j;
    }

    /*
     * The conversion function will use an O(log N) lookup method for each
     * value converted. However, if all of the following constraints are met
     * then we can build a perfect hash table and use an O(1) lookup method.
     *
     *	  A: The source data type size matches one of our native data type
     *	     sizes.
     *	     
     *	  B: After casting the source value bit pattern to a native type
     *	     the size of the range of values is less than 20% larger than
     *	     the number of values.
     *
     * If this special case is met then we use the source bit pattern cast as
     * a native integer type as an index into the `val2dst'. The values of
     * that array are the index numbers in the destination type or negative
     * if the entry is unused.
     */
    if (1==src->shared->size || sizeof(short)==src->shared->size || sizeof(int)==src->shared->size) {
	for (i=0; i<src->shared->u.enumer.nmembs; i++) {
	    if (1==src->shared->size) {
		n = *((signed char*)(src->shared->u.enumer.value+i));
	    } else if (sizeof(short)==src->shared->size) {
		n = *((short*)(src->shared->u.enumer.value+i*src->shared->size));
	    } else {
		n = *((int*)(src->shared->u.enumer.value+i*src->shared->size));
	    }
	    if (0==i) {
		domain[0] = domain[1] = n;
	    } else {
		domain[0] = MIN(domain[0], n);
		domain[1] = MAX(domain[1], n);
	    }
	}

	length = (domain[1]-domain[0])+1;
	if (src->shared->u.enumer.nmembs<2 ||
	    (double)length/src->shared->u.enumer.nmembs<1.2) {
	    priv->base = domain[0];
	    priv->length = length;
	    if (NULL==(map=H5MM_malloc(length*sizeof(int))))
		HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
	    for (i=0; i<length; i++)
                map[i] = -1; /*entry unused*/
	    for (i=0; i<src->shared->u.enumer.nmembs; i++) {
		if (1==src->shared->size) {
		    n = *((signed char*)(src->shared->u.enumer.value+i));
		} else if (sizeof(short)==src->shared->size) {
		    n = *((short*)(src->shared->u.enumer.value+i*src->shared->size));
		} else {
		    n = *((int*)(src->shared->u.enumer.value+i*src->shared->size));
		}
		n -= priv->base;
		assert(n>=0 && n<priv->length);
		assert(map[n]<0);
		map[n] = priv->src2dst[i];
	    }

	    /*
	     * Replace original src2dst array with our new one. The original
	     * was indexed by source member number while the new one is
	     * indexed by source values.
	     */
	    H5MM_xfree(priv->src2dst);
	    priv->src2dst = map;
	    HGOTO_DONE(SUCCEED);
	}
    }

    /* Sort source type by value and adjust src2dst[] appropriately */
    H5T_sort_value(src, priv->src2dst);

done:
    if (ret_value<0 && priv) {
	H5MM_xfree(priv->src2dst);
	H5MM_xfree(priv);
	cdata->priv = NULL;
    }
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_enum
 *
 * Purpose:	Converts one type of enumerated data to another.
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *              Monday, January  4, 1999
 *
 * Modifications:
 *		Robb Matzke, 1999-06-16
 *		Added support for non-zero strides. If BUF_STRIDE is non-zero
 *		then convert one value at each memory location advancing
 *		BUF_STRIDE bytes each time; otherwise assume both source and
 *		destination values are packed.
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
	      size_t buf_stride, size_t UNUSED bkg_stride, void *_buf,
              void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    uint8_t	*buf = (uint8_t*)_buf;	/*cast for pointer arithmetic	*/
    H5T_t	*src=NULL, *dst=NULL;	/*src and dst data types	*/
    uint8_t	*s=NULL, *d=NULL;	/*src and dst BUF pointers	*/
    int	src_delta, dst_delta;	/*conversion strides		*/
    int	n;			/*src value cast as native int	*/
    size_t	i;			/*counters			*/
    H5T_enum_struct_t *priv = (H5T_enum_struct_t*)(cdata->priv);
    H5P_genplist_t      *plist;         /*property list pointer         */
    H5T_conv_cb_t       cb_struct;      /*conversion callback structure */
    H5T_conv_ret_t      except_ret;     /*return of callback function   */
    herr_t      ret_value=SUCCEED;      /* Return value                 */
    
    FUNC_ENTER_NOAPI(H5T_conv_enum, FAIL);

    switch (cdata->command) {
        case H5T_CONV_INIT:
            /*
             * Determine if this conversion function applies to the conversion
             * path SRC_ID->DST_ID.  If not return failure; otherwise initialize
             * the `priv' field of `cdata' with information about the underlying
             * integer conversion.
             */
            if (NULL == (src = H5I_object(src_id)) ||
                    NULL == (dst = H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            assert (H5T_ENUM==src->shared->type);
            assert (H5T_ENUM==dst->shared->type);
            if (H5T_conv_enum_init(src, dst, cdata)<0)
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize private data");
            break;

        case H5T_CONV_FREE:
#ifdef H5T_DEBUG
            if (H5DEBUG(T)) {
                fprintf(H5DEBUG(T), "      Using %s mapping function%s\n",
                        priv->length?"O(1)":"O(log N)",
                        priv->length?"":", where N is the number of enum members");
            }
#endif
            if (priv) {
                H5MM_xfree(priv->src2dst);
                H5MM_xfree(priv);
            }
            cdata->priv = NULL;
            break;

        case H5T_CONV_CONV:
            if (NULL == (src = H5I_object(src_id)) ||
                    NULL == (dst = H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            assert (H5T_ENUM==src->shared->type);
            assert (H5T_ENUM==dst->shared->type);

            /* priv->src2dst map was computed for certain sort keys. Make sure those same
             * sort keys are used here during conversion. See H5T_conv_enum_init(). But
             * we actually don't care about the source type's order when doing the O(1)
             * conversion algorithm, which is turned on by non-zero priv->length */
            H5T_sort_name(dst, NULL);
            if (!priv->length) H5T_sort_value(src, NULL);
            
            /*
             * Direction of conversion.
             */
            if (buf_stride) {
                src_delta = dst_delta = (int)buf_stride;
                s = d = buf;
            } else if (dst->shared->size <= src->shared->size) {
                src_delta = (int)src->shared->size; /*overflow shouldn't be possible*/
                dst_delta = (int)dst->shared->size; /*overflow shouldn't be possible*/
                s = d = buf;
            } else {
                src_delta = -(int)src->shared->size; /*overflow shouldn't be possible*/
                dst_delta = -(int)dst->shared->size; /*overflow shouldn't be possible*/
                s = buf + (nelmts-1) * src->shared->size;
                d = buf + (nelmts-1) * dst->shared->size;
            }
            
            /* Get the plist structure */
            if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
                HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID");

            /* Get conversion exception callback property */
            if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0)
                HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback");
 
            for (i=0; i<nelmts; i++, s+=src_delta, d+=dst_delta) {
                if (priv->length) {
                    /* Use O(1) lookup */
                    if (1==src->shared->size) {
                        n = *((signed char*)s);
                    } else if (sizeof(short)==src->shared->size) {
                        n = *((short*)s);
                    } else {
                        n = *((int*)s);
                    }
                    n -= priv->base;

                    if (n<0 || n>=priv->length || priv->src2dst[n]<0) {
                        /*overflow*/
                        except_ret = H5T_CONV_UNHANDLED;
                        if(cb_struct.func) { /*If user's exception handler is present, use it*/
                            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, 
                                    s, d, cb_struct.user_data);
                        }
                        
                        if(except_ret == H5T_CONV_UNHANDLED) { 
                            HDmemset(d, 0xff, dst->shared->size);
                        } else if(except_ret == H5T_CONV_ABORT)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception")
                    } else {
                        HDmemcpy(d,
                                 dst->shared->u.enumer.value+priv->src2dst[n]*dst->shared->size,
                                 dst->shared->size);
                    }
                } else {
                    /* Use O(log N) lookup */
                    int lt = 0;
                    int rt = src->shared->u.enumer.nmembs;
                    int md, cmp;
                    while (lt<rt) {
                        md = (lt+rt)/2;
                        cmp = HDmemcmp(s, src->shared->u.enumer.value+md*src->shared->size,
                                       src->shared->size);
                        if (cmp<0) {
                            rt = md;
                        } else if (cmp>0) {
                            lt = md+1;
                        } else {
                            break;
                        }
                    }
                    if (lt>=rt) {
                        except_ret = H5T_CONV_UNHANDLED;
                        if(cb_struct.func) { /*If user's exception handler is present, use it*/
                            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, 
                                    src, d, cb_struct.user_data);
                        }
                        
                        if(except_ret == H5T_CONV_UNHANDLED) { 
                            HDmemset(d, 0xff, dst->shared->size);
                        } else if(except_ret == H5T_CONV_ABORT)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception")
                    } else {
                        HDmemcpy(d,
                                 dst->shared->u.enumer.value+priv->src2dst[md]*dst->shared->size,
                                 dst->shared->size);
                    }
                }
            }
            break;

        default:
            /* Some other command we don't know about yet.*/
            HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
    }

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_vlen
 *
 * Purpose:	Converts between VL data types in memory and on disk.
 *		This is a soft conversion function.  The algorithm is
 *		basically:
 *
 *      	For every VL struct in the main buffer:
 *		  1. Allocate space for temporary dst VL data (reuse buffer
 *		     if possible) 
 *                2. Copy VL data from src buffer into dst buffer
 *                3. Convert VL data into dst representation
 *                4. Allocate buffer in dst heap
 *		  5. Free heap objects storing old data
 *                6. Write dst VL data into dst heap
 *                7. Store (heap ID or pointer) and length in main dst buffer
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Quincey Koziol
 *		Wednesday, May 26, 1999
 *
 * Modifications:
 *
 *		Quincey Koziol, 2 July, 1999
 *		Enabled support for non-zero strides. If BUF_STRIDE is non-zero
 *		then convert one value at each memory location advancing
 *		BUF_STRIDE bytes each time; otherwise assume both source and
 *		destination values are packed.
 *
 *		Raymond Lu, 26 June, 2002
 *		Background buffer is used for freeing heap objects storing 
 * 		old data.  At this moment, it only frees the first level of 
 *		VL datatype.  It doesn't handle nested VL datatypes.    
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
	      size_t buf_stride, size_t bkg_stride, void *buf,
              void *bkg, hid_t dxpl_id)
{
    H5T_vlen_alloc_info_t _vl_alloc_info;       /* VL allocation info buffer */
    H5T_vlen_alloc_info_t *vl_alloc_info=&_vl_alloc_info;   /* VL allocation info */
    H5T_path_t	*tpath;			/* Type conversion path		     */
    hbool_t     noop_conv=FALSE;        /* Flag to indicate a noop conversion */
    hbool_t     write_to_file=FALSE;    /* Flag to indicate writing to file */
    hbool_t     parent_is_vlen;         /* Flag to indicate parent is vlen datatyp */
    hid_t   	tsrc_id = -1, tdst_id = -1;/*temporary type atoms	     */
    H5T_t	*src = NULL;		/*source data type		     */
    H5T_t	*dst = NULL;		/*destination data type		     */
    H5HG_t	bg_hobjid, parent_hobjid;
    uint8_t	*s;		        /*source buffer			*/
    uint8_t	*d;		        /*destination buffer		*/
    uint8_t	*b;		        /*background buffer		*/
    ssize_t	s_stride, d_stride;	/*src and dst strides		*/
    ssize_t	b_stride;	        /*bkg stride			*/
    size_t      safe;                   /*how many elements are safe to process in each pass */
    ssize_t 	seq_len;                /*the number of elements in the current sequence*/
    size_t	bg_seq_len=0;
    size_t	src_base_size, dst_base_size;/*source & destination base size*/
    void	*conv_buf=NULL;     	/*temporary conversion buffer 	     */
    size_t	conv_buf_size=0;  	/*size of conversion buffer in bytes */
    void	*tmp_buf=NULL;     	/*temporary background buffer 	     */
    size_t	tmp_buf_size=0;	        /*size of temporary bkg buffer	     */
    hbool_t     nested=FALSE;           /*flag of nested VL case             */
    size_t	elmtno;			/*element number counter	     */
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_vlen, FAIL);

    switch (cdata->command) {
        case H5T_CONV_INIT:
            /*
             * First, determine if this conversion function applies to the
             * conversion path SRC_ID-->DST_ID.  If not, return failure;
             * otherwise initialize the `priv' field of `cdata' with
             * information that remains (almost) constant for this
             * conversion path.
             */
            if (NULL == (src = H5I_object(src_id)) ||
                    NULL == (dst = H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            assert (H5T_VLEN==src->shared->type);
            assert (H5T_VLEN==dst->shared->type);

            /* Variable-length types don't need a background buffer */
            cdata->need_bkg = H5T_BKG_NO;

            break;

        case H5T_CONV_FREE:
            /* QAK - Nothing to do currently */
            break;

        case H5T_CONV_CONV:
            /*
             * Conversion.
             */
            if (NULL == (src = H5I_object(src_id)) ||
                    NULL == (dst = H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");

            /* Initialize source & destination strides */
            if (buf_stride) {
                assert(buf_stride>=src->shared->size);
                assert(buf_stride>=dst->shared->size);
                s_stride = d_stride = buf_stride;
            } else {
                s_stride = src->shared->size;
                d_stride = dst->shared->size;
            }
            if(bkg) {
                if(bkg_stride)
                    b_stride=bkg_stride;
                else
                    b_stride=d_stride;
            } /* end if */
            else
                b_stride=0;

            /* Get the size of the base types in src & dst */
            src_base_size=H5T_get_size(src->shared->parent);
            dst_base_size=H5T_get_size(dst->shared->parent);

            /* Set up conversion path for base elements */
            if (NULL==(tpath=H5T_path_find(src->shared->parent, dst->shared->parent, NULL, NULL, dxpl_id))) {
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest datatypes");
            } else if (!H5T_path_noop(tpath)) {
                if ((tsrc_id = H5I_register(H5I_DATATYPE, H5T_copy(src->shared->parent, H5T_COPY_ALL)))<0 ||
                        (tdst_id = H5I_register(H5I_DATATYPE, H5T_copy(dst->shared->parent, H5T_COPY_ALL)))<0)
                    HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion");
            } else
                noop_conv=TRUE;

            /* Check if we need a temporary buffer for this conversion */
            parent_is_vlen=H5T_detect_class(dst->shared->parent,H5T_VLEN);
            if(tpath->cdata.need_bkg || parent_is_vlen) {
                /* Set up initial background buffer */
                tmp_buf_size=MAX(src_base_size,dst_base_size);
                if ((tmp_buf=H5FL_BLK_MALLOC(vlen_seq,tmp_buf_size))==NULL)
                    HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
            } /* end if */
    
            /* Get the allocation info */
            if(H5T_vlen_get_alloc_info(dxpl_id,&vl_alloc_info)<0)
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info");

            /* Set flags to indicate we are writing to or reading from the file */
            if(dst->shared->u.vlen.f!=NULL)
                write_to_file=TRUE;

            /* Set the flag for nested VL case */
            if(write_to_file && parent_is_vlen && bkg!=NULL)
                nested=1;

            /* The outer loop of the type conversion macro, controlling which */
            /* direction the buffer is walked */
            while (nelmts>0) {
                /* Check if we need to go backwards through the buffer */
                if(d_stride>s_stride) {
                    /* Compute the number of "safe" destination elements at */
                    /* the end of the buffer (Those which don't overlap with */
                    /* any source elements at the beginning of the buffer) */
                    safe=nelmts-(((nelmts*s_stride)+(d_stride-1))/d_stride);

                    /* If we're down to the last few elements, just wrap up */
                    /* with a "real" reverse copy */
                    if(safe<2) {
                        s = (uint8_t*)buf+(nelmts-1)*s_stride;
                        d = (uint8_t*)buf+(nelmts-1)*d_stride;
                        b = (uint8_t*)bkg+(nelmts-1)*b_stride;
                        s_stride = -s_stride;
                        d_stride = -d_stride;
                        b_stride = -b_stride;

                        safe=nelmts;
                    } /* end if */
                    else {
                        s = (uint8_t*)buf+(nelmts-safe)*s_stride;
                        d = (uint8_t*)buf+(nelmts-safe)*d_stride;
                        b = (uint8_t*)bkg+(nelmts-safe)*b_stride;
                    } /* end else */
                } /* end if */
                else {
                    /* Single forward pass over all data */
                    s = d = buf;
                    b = bkg;
                    safe=nelmts;
                } /* end else */

                for (elmtno=0; elmtno<safe; elmtno++) {
                    /* Check for "nil" source sequence */
                    if((*(src->shared->u.vlen.isnull))(src->shared->u.vlen.f,s)) {
                        /* Write "nil" sequence to destination location */
                        if((*(dst->shared->u.vlen.setnull))(dst->shared->u.vlen.f,dxpl_id,d,b)<0)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't set VL data to 'nil'");
                    } /* end if */
                    else {
                        /* Get length of element sequences */
                        if((seq_len=(*(src->shared->u.vlen.getlen))(s))<0)
                            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "incorrect length");

                        /* If we are reading from memory and there is no conversion, just get the pointer to sequence */
                        if(write_to_file && noop_conv) {
                            /* Get direct pointer to sequence */
                            if((conv_buf=(*(src->shared->u.vlen.getptr))(s))==NULL)
                                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid source pointer");
                        } /* end if */
                        else {
                            size_t	src_size, dst_size;     /*source & destination total size in bytes*/

                            src_size=seq_len*src_base_size;
                            dst_size=seq_len*dst_base_size;

                            /* Check if conversion buffer is large enough, resize if
                             * necessary */      
                            if(conv_buf_size<MAX(src_size,dst_size)) {
                                /* Only allocate conversion buffer in H5T_VLEN_MIN_CONF_BUF_SIZE increments */
                                conv_buf_size=((MAX(src_size,dst_size)/H5T_VLEN_MIN_CONF_BUF_SIZE)+1)*H5T_VLEN_MIN_CONF_BUF_SIZE;
                                if((conv_buf=H5FL_BLK_REALLOC(vlen_seq,conv_buf, conv_buf_size))==NULL)
                                    HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
                            } /* end if */

                            /* Read in VL sequence */
                            if((*(src->shared->u.vlen.read))(src->shared->u.vlen.f,dxpl_id,s,conv_buf,src_size)<0)
                                HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data");
                        } /* end else */

                        if(!noop_conv) {
                            /* Check if temporary buffer is large enough, resize if necessary */
                            /* (Chain off the conversion buffer size) */
                            if(tmp_buf && tmp_buf_size<conv_buf_size) {
                                /* Set up initial background buffer */
                                tmp_buf_size=conv_buf_size;
                                if((tmp_buf=H5FL_BLK_REALLOC(vlen_seq,tmp_buf,tmp_buf_size))==NULL)
                                    HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
                            } /* end if */

                            /* If we are writing and there is a nested VL type, read 
                             * the sequence into the background buffer */
                            if(nested) {
                                uint8_t *tmp=b;
                                UINT32DECODE(tmp, bg_seq_len);

                                if(bg_seq_len>0) {
                                    if(tmp_buf_size<(bg_seq_len*MAX(src_base_size, dst_base_size))) {
                                        tmp_buf_size=(bg_seq_len*MAX(src_base_size, dst_base_size));
                                        if((tmp_buf=H5FL_BLK_REALLOC(vlen_seq,tmp_buf, tmp_buf_size))==NULL)
                                            HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
                                    }
                                    H5F_addr_decode(dst->shared->u.vlen.f, (const uint8_t **)&tmp, &(bg_hobjid.addr));
                                    INT32DECODE(tmp, bg_hobjid.idx);
                                    if(H5HG_read(dst->shared->u.vlen.f,dxpl_id,&bg_hobjid,tmp_buf)==NULL)
                                        HGOTO_ERROR (H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL sequence into background buffer");
                                } /* end if */

                                /* If the sequence gets shorter, pad out the original sequence with zeros */
                                H5_CHECK_OVERFLOW(bg_seq_len,size_t,ssize_t);
                                if((ssize_t)bg_seq_len<seq_len) {
                                    HDmemset((uint8_t *)tmp_buf+dst_base_size*bg_seq_len,0,(seq_len-bg_seq_len)*dst_base_size);
                                } /* end if */
                            } /* end if */

                            /* Convert VL sequence */
                            H5_CHECK_OVERFLOW(seq_len,ssize_t,size_t);
                            if (H5T_convert(tpath, tsrc_id, tdst_id, (size_t)seq_len, 0, 0, conv_buf, tmp_buf, dxpl_id)<0)
                                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed");
                        } /* end if */

                        /* Write sequence to destination location */
                        if((*(dst->shared->u.vlen.write))(dst->shared->u.vlen.f,dxpl_id,vl_alloc_info,d,conv_buf, b, (size_t)seq_len, dst_base_size)<0)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write VL data");

                        if(!noop_conv) {
                            /* For nested VL case, free leftover heap objects from the deeper level if the length of new data elements is shorter than the old data elements.*/
                            H5_CHECK_OVERFLOW(bg_seq_len,size_t,ssize_t);
                            if(nested && seq_len<(ssize_t)bg_seq_len) {
                                size_t parent_seq_len;
                                size_t     u;

                                uint8_t *tmp_p=tmp_buf;
                                tmp_p += seq_len*dst_base_size;
                                for(u=0; u<(bg_seq_len-seq_len); u++) {
                                    UINT32DECODE(tmp_p, parent_seq_len);
                                    if(parent_seq_len>0) {
                                        H5F_addr_decode(dst->shared->u.vlen.f, (const uint8_t **)&tmp_p, &(parent_hobjid.addr));
                                        INT32DECODE(tmp_p, parent_hobjid.idx);
                                        if(H5HG_remove(dst->shared->u.vlen.f, dxpl_id,&parent_hobjid)<0)
                                            HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object");
                                    }
                                }
                            } /* end if */
                        } /* end if */
                    } /* end else */

                    /* Advance pointers */
                    s += s_stride;
                    d += d_stride;
                    b += b_stride;
                } /* end for */

                /* Decrement number of elements left to convert */
                nelmts-=safe;
            } /* end while */

            /* Release the temporary datatype IDs used */
            if (tsrc_id >= 0)
                H5I_dec_ref(tsrc_id);
            if (tdst_id >= 0)
                H5I_dec_ref(tdst_id);
            break;

        default:    /* Some other command we don't know about yet.*/
            HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
    }   /* end switch */
    
done:
    /* If the conversion buffer doesn't need to be freed, reset its pointer */
    if(write_to_file && noop_conv)
        conv_buf=NULL;
    /* Release the conversion buffer (always allocated, except on errors) */
    if(conv_buf!=NULL)
        H5FL_BLK_FREE(vlen_seq,conv_buf);
    /* Release the background buffer, if we have one */
    if(tmp_buf!=NULL)
        H5FL_BLK_FREE(vlen_seq,tmp_buf);

    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_array
 *
 * Purpose:	Converts between array data types in memory and on disk.
 *		This is a soft conversion function.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Quincey Koziol
 *		Monday, November 6, 2000
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
	      size_t buf_stride, size_t bkg_stride, void *_buf,
              void UNUSED *_bkg, hid_t dxpl_id)
{
    H5T_path_t	*tpath;		        /* Type conversion path		     */
    hid_t       tsrc_id = -1, tdst_id = -1;/*temporary type atoms	     */
    H5T_t	*src = NULL;	        /*source data type		     */
    H5T_t	*dst = NULL;	        /*destination data type		     */
    uint8_t	*sp, *dp;	        /*source and dest traversal ptrs     */
    size_t	src_delta, dst_delta;	/*source & destination stride	     */
    int	        direction;		/*direction of traversal	     */
    size_t	elmtno;			/*element number counter	     */
    int         i;                      /* local index variable */
    void	*bkg_buf=NULL;     	/*temporary background buffer 	     */
    size_t	bkg_buf_size=0;	        /*size of background buffer in bytes */
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_array, FAIL);

    switch (cdata->command) {
        case H5T_CONV_INIT:
            /*
             * First, determine if this conversion function applies to the
             * conversion path SRC_ID-->DST_ID.  If not, return failure;
             * otherwise initialize the `priv' field of `cdata' with
             * information that remains (almost) constant for this
             * conversion path.
             */
            if (NULL == (src = H5I_object(src_id)) ||
                    NULL == (dst = H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            assert (H5T_ARRAY==src->shared->type);
            assert (H5T_ARRAY==dst->shared->type);

            /* Check the number and sizes of the dimensions */
            if(src->shared->u.array.ndims!=dst->shared->u.array.ndims)
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "array datatypes do not have the same number of dimensions");
            for(i=0; i<src->shared->u.array.ndims; i++)
                if(src->shared->u.array.dim[i]!=dst->shared->u.array.dim[i])
                    HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "array datatypes do not have the same sizes of dimensions");
#ifdef LATER
            for(i=0; i<src->shared->u.array.ndims; i++)
                if(src->shared->u.array.perm[i]!=dst->shared->u.array.perm[i])
                    HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "array datatypes do not have the same dimension permutations");
#endif /* LATER */

            /* Array datatypes don't need a background buffer */
            cdata->need_bkg = H5T_BKG_NO;

            break;

        case H5T_CONV_FREE:
            /* QAK - Nothing to do currently */
            break;

        case H5T_CONV_CONV:
            /*
             * Conversion.
             */
            if (NULL == (src = H5I_object(src_id)) ||
                    NULL == (dst = H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");

            /*
             * Do we process the values from beginning to end or vice
             * versa? Also, how many of the elements have the source and
             * destination areas overlapping?
             */
            if (src->shared->size>=dst->shared->size || buf_stride>0) {
                sp = dp = (uint8_t*)_buf;
                direction = 1;
            } else {
                sp = (uint8_t*)_buf + (nelmts-1) *
                     (buf_stride ? buf_stride : src->shared->size);
                dp = (uint8_t*)_buf + (nelmts-1) *
                     (buf_stride ? buf_stride : dst->shared->size);
                direction = -1;
            }

            /*
             * Direction & size of buffer traversal.
             */
            src_delta = direction * (buf_stride ? buf_stride : src->shared->size);
            dst_delta = direction * (buf_stride ? buf_stride : dst->shared->size);

            /* Set up conversion path for base elements */
            if (NULL==(tpath=H5T_path_find(src->shared->parent, dst->shared->parent, NULL, NULL, dxpl_id))) {
                HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest datatypes");
            } else if (!H5T_path_noop(tpath)) {
                if ((tsrc_id = H5I_register(H5I_DATATYPE, H5T_copy(src->shared->parent, H5T_COPY_ALL)))<0 ||
                        (tdst_id = H5I_register(H5I_DATATYPE, H5T_copy(dst->shared->parent, H5T_COPY_ALL)))<0)
                    HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion");
            }

            /* Check if we need a background buffer for this conversion */
            if(tpath->cdata.need_bkg) {
                /* Allocate background buffer */
                bkg_buf_size=src->shared->u.array.nelem*MAX(src->shared->size,dst->shared->size);
                if ((bkg_buf=H5FL_BLK_CALLOC(array_seq,bkg_buf_size))==NULL)
                    HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
            } /* end if */

            /* Perform the actual conversion */
            for (elmtno=0; elmtno<nelmts; elmtno++) {
                /* Copy the source array into the correct location for the destination */
                HDmemmove(dp, sp, src->shared->size);

                /* Convert array */
                if (H5T_convert(tpath, tsrc_id, tdst_id, src->shared->u.array.nelem, 0, bkg_stride, dp, bkg_buf, dxpl_id)<0)
                    HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed");

                /* Advance the source & destination pointers */
                sp += src_delta;
                dp += dst_delta;
            }

            /* Release the background buffer, if we have one */
            if(bkg_buf!=NULL)
                H5FL_BLK_FREE(array_seq,bkg_buf);

            /* Release the temporary datatype IDs used */
            if (tsrc_id >= 0)
                H5I_dec_ref(tsrc_id);
            if (tdst_id >= 0)
                H5I_dec_ref(tdst_id);
            break;

        default:    /* Some other command we don't know about yet.*/
            HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
    }   /* end switch */
    
done:
    FUNC_LEAVE_NOAPI(ret_value);
}   /* end H5T_conv_array() */


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_i_i
 *
 * Purpose:	Convert one integer type to another.  This is the catch-all
 *		function for integer conversions and is probably not
 *		particularly fast.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Robb Matzke
 *		Wednesday, June 10, 1998
 *
 * Modifications:
 *		Robb Matzke, 7 Jul 1998
 *		Added overflow handling.
 *
 *		Robb Matzke, 1999-06-16
 *		Added support for non-zero strides. If BUF_STRIDE is non-zero
 *		then convert one value at each memory location advancing
 *		BUF_STRIDE bytes each time; otherwise assume both source and
 *		destination values are packed.
 *
 *              Raymond Lu
 *              Wednesday, April 21, 2004
 *              There is a new design for exception handling like overflow,
 *              which is passed in as a transfer property.
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
	      size_t buf_stride, size_t UNUSED bkg_stride, void *buf,
              void UNUSED *bkg, hid_t dxpl_id)
{
    H5T_t	*src = NULL;		/*source data type		*/
    H5T_t	*dst = NULL;		/*destination data type		*/
    int		direction;		/*direction of traversal	*/
    size_t	elmtno;			/*element number		*/
    size_t	half_size;		/*half the type size		*/
    size_t	olap;			/*num overlapping elements	*/
    uint8_t	*s, *sp, *d, *dp;	/*source and dest traversal ptrs*/
    uint8_t     *src_rev;               /*order-reversed source buffer  */
    uint8_t	dbuf[64];		/*temp destination buffer	*/
    size_t	first;
    ssize_t	sfirst;			/*a signed version of `first'	*/
    size_t	i;                      /*Local index variables         */
    H5P_genplist_t      *plist;         /*property list pointer         */
    H5T_conv_cb_t       cb_struct={NULL, NULL};      /*conversion callback structure */
    H5T_conv_ret_t      except_ret;     /*return of callback function   */
    hbool_t             reverse;        /*if reverse the order of destination        */
    herr_t      ret_value=SUCCEED;       /* Return value */
    
    FUNC_ENTER_NOAPI(H5T_conv_i_i, FAIL);

    switch (cdata->command) {
        case H5T_CONV_INIT:
            if (NULL==(src=H5I_object(src_id)) ||
                    NULL==(dst=H5I_object(dst_id)))
                HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            if (H5T_ORDER_LE!=src->shared->u.atomic.order &&
                    H5T_ORDER_BE!=src->shared->u.atomic.order)
                HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
            if (H5T_ORDER_LE!=dst->shared->u.atomic.order &&
                    H5T_ORDER_BE!=dst->shared->u.atomic.order)
                HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
            if (dst->shared->size>sizeof dbuf)
                HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large");
            cdata->need_bkg = H5T_BKG_NO;
            break;
            
        case H5T_CONV_FREE:
            break;

        case H5T_CONV_CONV:
            /* Get the data types */
            if (NULL==(src=H5I_object(src_id)) ||
                    NULL==(dst=H5I_object(dst_id)))
                HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");

            /*
             * Do we process the values from beginning to end or vice versa? Also,
             * how many of the elements have the source and destination areas
             * overlapping?
             */
            if (src->shared->size==dst->shared->size || buf_stride) {
                sp = dp = (uint8_t*)buf;
                direction = 1;
                olap = nelmts;
            } else if (src->shared->size>=dst->shared->size) {
                double olap_d = HDceil((double)(dst->shared->size)/
                                       (double)(src->shared->size-dst->shared->size));
                
                olap = (size_t)olap_d;
                sp = dp = (uint8_t*)buf;
                direction = 1;
            } else {
                double olap_d = HDceil((double)(src->shared->size)/
                                       (double)(dst->shared->size-src->shared->size));
                olap = (size_t)olap_d;
                sp = (uint8_t*)buf + (nelmts-1) * src->shared->size;
                dp = (uint8_t*)buf + (nelmts-1) * dst->shared->size;
                direction = -1;
            }

            /* Get the plist structure */
            if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
                HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID");

            /* Get conversion exception callback property */
            if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0)
                HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback");

            /* Allocate space for order-reversed source buffer */
            src_rev = (uint8_t*)H5MM_calloc(src->shared->size);

            /* The conversion loop */
            for (elmtno=0; elmtno<nelmts; elmtno++) {

                /*
                 * If the source and destination buffers overlap then use a
                 * temporary buffer for the destination.
                 */
                if (direction>0) {
                    s = sp;
                    d = elmtno<olap ? dbuf : dp;
                } else {
                    s = sp;
                    d = elmtno+olap >= nelmts ? dbuf : dp;
                }
#ifndef NDEBUG
                /* I don't quite trust the overlap calculations yet --rpm */
                if (d==dbuf) {
                    assert ((dp>=sp && dp<sp+src->shared->size) || (sp>=dp && sp<dp+dst->shared->size));
                } else {
                    assert ((dp<sp && dp+dst->shared->size<=sp) || (sp<dp && sp+src->shared->size<=dp));
                }
#endif
                
                /*
                 * Put the data in little endian order so our loops aren't so
                 * complicated.  We'll do all the conversion stuff assuming
                 * little endian and then we'll fix the order at the end.
                 */
                if (H5T_ORDER_BE==src->shared->u.atomic.order) {
                    half_size = src->shared->size/2;
                    for (i=0; i<half_size; i++) {
                        uint8_t tmp = s[src->shared->size-(i+1)];
                        s[src->shared->size-(i+1)] = s[i];
                        s[i] = tmp;
                    }
                }

                /*
                 * What is the bit number for the msb bit of S which is set? The
                 * bit number is relative to the significant part of the number.
                 */
                sfirst = H5T_bit_find (s, src->shared->u.atomic.offset, src->shared->u.atomic.prec,
                                       H5T_BIT_MSB, TRUE);
                first = (size_t)sfirst;

                /* Set these variables to default */
                except_ret = H5T_CONV_UNHANDLED;
                reverse    = TRUE;

                if (sfirst<0) {
                    /*
                     * The source has no bits set and must therefore be zero.
                     * Set the destination to zero.
                     */
                    H5T_bit_set (d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, FALSE);
                        
                } else if (H5T_SGN_NONE==src->shared->u.atomic.u.i.sign &&
                           H5T_SGN_NONE==dst->shared->u.atomic.u.i.sign) {
                    /*
                     * Source and destination are both unsigned, but if the
                     * source has more precision bits than the destination then
                     * it's possible to overflow.  When overflow occurs the
                     * destination will be set to the maximum possible value.
                     */
                    if (src->shared->u.atomic.prec <= dst->shared->u.atomic.prec) {
                        H5T_bit_copy (d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset,
                              src->shared->u.atomic.prec);
                        H5T_bit_set (d, dst->shared->u.atomic.offset+src->shared->u.atomic.prec,
                             dst->shared->u.atomic.prec-src->shared->u.atomic.prec, FALSE);
                    } else if (first>=dst->shared->u.atomic.prec) {
                        /*overflow*/
                        if(cb_struct.func) { /*If user's exception handler is present, use it*/
                            H5T_reverse_order(src_rev, s, src->shared->size, src->shared->u.atomic.order); /*reverse order first*/
                            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, 
                                    src_rev, d, cb_struct.user_data);
                        }
                        
                        if(except_ret == H5T_CONV_UNHANDLED) { 
                            H5T_bit_set (d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, TRUE);
                        } else if(except_ret == H5T_CONV_ABORT)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception")
                        else if(except_ret == H5T_CONV_HANDLED)
                            /*Don't reverse because user handles it already*/
                            reverse = FALSE;
                    } else {
                        H5T_bit_copy (d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset,
                              dst->shared->u.atomic.prec);
                    }
                    
                } else if (H5T_SGN_2==src->shared->u.atomic.u.i.sign &&
                           H5T_SGN_NONE==dst->shared->u.atomic.u.i.sign) {
                    /*
                     * If the source is signed and the destination isn't then we
                     * can have overflow if the source contains more bits than
                     * the destination (destination is set to the maximum
                     * possible value) or overflow if the source is negative
                     * (destination is set to zero).
                     */
                    if (first+1 == src->shared->u.atomic.prec) {
                        /*overflow - source is negative*/
                        if(cb_struct.func) { /*If user's exception handler is present, use it*/
                            H5T_reverse_order(src_rev, s, src->shared->size, src->shared->u.atomic.order); /*reverse order first*/
                            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW, src_id, dst_id, 
                                    src_rev, d, cb_struct.user_data);
                        }
                        
                        if(except_ret == H5T_CONV_UNHANDLED) { 
                            H5T_bit_set (d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, FALSE);
                        } else if(except_ret == H5T_CONV_ABORT)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception")
                        else if(except_ret == H5T_CONV_HANDLED)
                            /*Don't reverse because user handles it already*/
                            reverse = FALSE;
                    } else if (src->shared->u.atomic.prec < dst->shared->u.atomic.prec) {
                        H5T_bit_copy (d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset,
                              src->shared->u.atomic.prec-1);
                        H5T_bit_set (d, dst->shared->u.atomic.offset+src->shared->u.atomic.prec-1,
                             (dst->shared->u.atomic.prec-src->shared->u.atomic.prec)+1, FALSE);
                    } else if (first>=dst->shared->u.atomic.prec) {
                        /*overflow - source is positive*/
                        if(cb_struct.func) { /*If user's exception handler is present, use it*/
                            H5T_reverse_order(src_rev, s, src->shared->size, src->shared->u.atomic.order); /*reverse order first*/
                            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, 
                                    src_rev, d, cb_struct.user_data);
                        }
                        
                        if(except_ret == H5T_CONV_UNHANDLED)
                            H5T_bit_set (d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec, TRUE);
                        else if(except_ret == H5T_CONV_ABORT)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception")
                        else if(except_ret == H5T_CONV_HANDLED)
                            /*Don't reverse because user handles it already*/
                            reverse = FALSE;
                    } else {
                        H5T_bit_copy (d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset,
                              dst->shared->u.atomic.prec);
                    }
                    
                } else if (H5T_SGN_NONE==src->shared->u.atomic.u.i.sign &&
                           H5T_SGN_2==dst->shared->u.atomic.u.i.sign) {
                    /*
                     * If the source is not signed but the destination is then
                     * overflow can occur in which case the destination is set to
                     * the largest possible value (all bits set except the msb).
                     */
                    if (first+1 >= dst->shared->u.atomic.prec) {
                        /*overflow*/
                        if(cb_struct.func) { /*If user's exception handler is present, use it*/
                            H5T_reverse_order(src_rev, s, src->shared->size, src->shared->u.atomic.order); /*reverse order first*/
                            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, 
                                    src_rev, d, cb_struct.user_data);
                        }
                        
                        if(except_ret == H5T_CONV_UNHANDLED) { 
                            H5T_bit_set (d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec-1, TRUE);
                            H5T_bit_set (d, (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec-1), 1, FALSE);
                        } else if(except_ret == H5T_CONV_ABORT)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception")
                        else if(except_ret == H5T_CONV_HANDLED)
                            /*Don't reverse because user handles it already*/
                            reverse = FALSE;
                    } else if (src->shared->u.atomic.prec<dst->shared->u.atomic.prec) {
                        H5T_bit_copy (d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset,
                              src->shared->u.atomic.prec);
                        H5T_bit_set (d, dst->shared->u.atomic.offset+src->shared->u.atomic.prec,
                             dst->shared->u.atomic.prec-src->shared->u.atomic.prec, FALSE);
                    } else {
                        H5T_bit_copy (d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset,
                              dst->shared->u.atomic.prec);
                    }
                } else if (first+1 == src->shared->u.atomic.prec) {
                    /*
                     * Both the source and the destination are signed and the
                     * source value is negative.  We could experience overflow
                     * if the destination isn't wide enough in which case the
                     * destination is set to a negative number with the largest
                     * possible magnitude.
                     */
                    ssize_t sfz = H5T_bit_find (s, src->shared->u.atomic.offset,
                                    src->shared->u.atomic.prec-1, H5T_BIT_MSB, FALSE);
                    size_t fz = (size_t)sfz;
                    
                    if (sfz>=0 && fz+1>=dst->shared->u.atomic.prec) {
                        /*overflow*/
                        if(cb_struct.func) { /*If user's exception handler is present, use it*/
                            H5T_reverse_order(src_rev, s, src->shared->size, src->shared->u.atomic.order); /*reverse order first*/
                            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW, src_id, dst_id, 
                                    src_rev, d, cb_struct.user_data);
                        }
                        
                        if(except_ret == H5T_CONV_UNHANDLED) { 
                            H5T_bit_set (d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec-1, FALSE);
                            H5T_bit_set (d, (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec-1), 1, TRUE);
                        } else if(except_ret == H5T_CONV_ABORT)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception")
                        else if(except_ret == H5T_CONV_HANDLED)
                            /*Don't reverse because user handles it already*/
                            reverse = FALSE;
                    } else if (src->shared->u.atomic.prec<dst->shared->u.atomic.prec) {
                        H5T_bit_copy (d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, src->shared->u.atomic.prec);
                        H5T_bit_set (d, dst->shared->u.atomic.offset+src->shared->u.atomic.prec, dst->shared->u.atomic.prec-src->shared->u.atomic.prec, TRUE);
                    } else {
                        H5T_bit_copy (d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset, dst->shared->u.atomic.prec);
                    }
                    
                } else {
                    /*
                     * Source and destination are both signed but the source
                     * value is positive.  We could have an overflow in which
                     * case the destination is set to the largest possible
                     * positive value.
                     */
                    if (first+1>=dst->shared->u.atomic.prec) {
                        /*overflow*/
                        if(cb_struct.func) { /*If user's exception handler is present, use it*/
                            H5T_reverse_order(src_rev, s, src->shared->size, src->shared->u.atomic.order); /*reverse order first*/
                            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, 
                                    cb_struct.user_data);
                        }
                        
                        if(except_ret == H5T_CONV_UNHANDLED) { 
                            H5T_bit_set (d, dst->shared->u.atomic.offset, dst->shared->u.atomic.prec-1, TRUE);
                            H5T_bit_set (d, (dst->shared->u.atomic.offset + dst->shared->u.atomic.prec-1), 1, FALSE);
                        } else if(except_ret == H5T_CONV_ABORT)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception")
                        else if(except_ret == H5T_CONV_HANDLED)
                            /*Don't reverse because user handles it already*/
                            reverse = FALSE;
                    } else if (src->shared->u.atomic.prec<dst->shared->u.atomic.prec) {
                        H5T_bit_copy (d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset,
                              src->shared->u.atomic.prec);
                        H5T_bit_set (d, dst->shared->u.atomic.offset+src->shared->u.atomic.prec,
                             dst->shared->u.atomic.prec-src->shared->u.atomic.prec, FALSE);
                    } else {
                        H5T_bit_copy (d, dst->shared->u.atomic.offset, s, src->shared->u.atomic.offset,
                              dst->shared->u.atomic.prec);
                    }
                }

                /*
                 * Set padding areas in destination.
                 */
                if (dst->shared->u.atomic.offset>0) {
                    assert (H5T_PAD_ZERO==dst->shared->u.atomic.lsb_pad || H5T_PAD_ONE==dst->shared->u.atomic.lsb_pad);
                    H5T_bit_set (d, 0, dst->shared->u.atomic.offset, (hbool_t)(H5T_PAD_ONE==dst->shared->u.atomic.lsb_pad));
                }
                if (dst->shared->u.atomic.offset+dst->shared->u.atomic.prec!=8*dst->shared->size) {
                    assert (H5T_PAD_ZERO==dst->shared->u.atomic.msb_pad || H5T_PAD_ONE==dst->shared->u.atomic.msb_pad);
                    H5T_bit_set (d, dst->shared->u.atomic.offset+dst->shared->u.atomic.prec,
                                 8*dst->shared->size - (dst->shared->u.atomic.offset+ dst->shared->u.atomic.prec),
                                 (hbool_t)(H5T_PAD_ONE==dst->shared->u.atomic.msb_pad));
                }

                /*
                 * Put the destination in the correct byte order.  See note at
                 * beginning of loop.
                 */
                if (H5T_ORDER_BE==dst->shared->u.atomic.order && reverse) {
                    half_size = dst->shared->size/2;
                    for (i=0; i<half_size; i++) {
                        uint8_t tmp = d[dst->shared->size-(i+1)];
                        d[dst->shared->size-(i+1)] = d[i];
                        d[i] = tmp;
                    }
                }

                /*
                 * If we had used a temporary buffer for the destination then we
                 * should copy the value to the true destination buffer.
                 */
                if (d==dbuf)
                    HDmemcpy (dp, d, dst->shared->size);
                if (buf_stride) {
                    sp += direction * buf_stride;
                    dp += direction * buf_stride;
                } else {
                    sp += direction * src->shared->size;
                    dp += direction * dst->shared->size;
                }
            }
            
            H5MM_free(src_rev);

            break;

        default:
            HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
    }

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_f_f
 *
 * Purpose:	Convert one floating point type to another.  This is a catch
 *		all for floating point conversions and is probably not
 *		particularly fast!
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Robb Matzke
 *		Tuesday, June 23, 1998
 *
 * Modifications:
 *		Robb Matzke, 7 Jul 1998
 *		Added overflow handling.
 *
 *		Robb Matzke, 1999-06-16
 *		Added support for non-zero strides. If BUF_STRIDE is non-zero
 *		then convert one value at each memory location advancing
 *		BUF_STRIDE bytes each time; otherwise assume both source and
 *		destination values are packed.
 *
 *              Robb Matzke, 2001-02-02
 *              Oops, forgot to increment the exponent when rounding the
 *              significand resulted in a carry. Thanks to Guillaume Colin
 *              de Verdiere for finding this one!
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
    size_t buf_stride, size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
    hid_t dxpl_id)
{
    /* Traversal-related variables */
    H5T_t	*src_p;			/*source data type		*/
    H5T_t	*dst_p;			/*destination data type		*/
    H5T_atomic_t src;			/*atomic source info		*/
    H5T_atomic_t dst;			/*atomic destination info	*/
    int	direction;		        /*forward or backward traversal	*/
    size_t	elmtno;			/*element number		*/
    size_t	half_size;		/*half the type size		*/
    size_t	olap;			/*num overlapping elements	*/
    ssize_t	bitno;			/*bit number			*/
    uint8_t	*s, *sp, *d, *dp;	/*source and dest traversal ptrs*/
    uint8_t     *src_rev;               /*order-reversed source buffer  */
    uint8_t	dbuf[64];		/*temp destination buffer	*/

    /* Conversion-related variables */
    hssize_t	expo;			/*exponent			*/
    hssize_t	expo_max;		/*maximum possible dst exponent	*/
    size_t	msize=0;		/*useful size of mantissa in src*/
    size_t	mpos;			/*offset to useful mant is src	*/
    size_t	mrsh;			/*amount to right shift mantissa*/
    hbool_t	carry=0;		/*carry after rounding mantissa	*/
    size_t	i;			/*miscellaneous counters	*/
    size_t	implied;		/*destination implied bits	*/
    H5P_genplist_t      *plist;         /*property list pointer         */
    H5T_conv_cb_t       cb_struct={NULL, NULL};      /*conversion callback structure */
    H5T_conv_ret_t      except_ret;     /*return of callback function   */
    hbool_t             reverse;        /*if reverse the order of destination        */
    herr_t      ret_value=SUCCEED;      /*return value                 */
    
    FUNC_ENTER_NOAPI(H5T_conv_f_f, FAIL);

    switch (cdata->command) {
        case H5T_CONV_INIT:
            if (NULL==(src_p=H5I_object(src_id)) ||
                    NULL==(dst_p=H5I_object(dst_id)))
                HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            src = src_p->shared->u.atomic;
            dst = dst_p->shared->u.atomic;
            if (H5T_ORDER_LE!=src.order && H5T_ORDER_BE!=src.order)
                HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
            if (H5T_ORDER_LE!=dst.order && H5T_ORDER_BE!=dst.order)
                HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
            if (dst_p->shared->size>sizeof(dbuf))
                HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large");
            if (8*sizeof(expo)-1<src.u.f.esize || 8*sizeof(expo)-1<dst.u.f.esize)
                HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large");
            cdata->need_bkg = H5T_BKG_NO;
            break;

        case H5T_CONV_FREE:
            break;

        case H5T_CONV_CONV:
            /* Get the data types */
            if (NULL==(src_p=H5I_object(src_id)) ||
                    NULL==(dst_p=H5I_object(dst_id)))
                HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            src = src_p->shared->u.atomic;
            dst = dst_p->shared->u.atomic;
            expo_max = ((hssize_t)1 << dst.u.f.esize) - 1;

            /*
             * Do we process the values from beginning to end or vice versa? Also,
             * how many of the elements have the source and destination areas
             * overlapping?
             */
            if (src_p->shared->size==dst_p->shared->size || buf_stride) {
                sp = dp = (uint8_t*)buf;
                direction = 1;
                olap = nelmts;
            } else if (src_p->shared->size>=dst_p->shared->size) {
                double olap_d = HDceil((double)(dst_p->shared->size)/
                                       (double)(src_p->shared->size-dst_p->shared->size));
                olap = (size_t)olap_d;
                sp = dp = (uint8_t*)buf;
                direction = 1;
            } else {
                double olap_d = HDceil((double)(src_p->shared->size)/
                                       (double)(dst_p->shared->size-src_p->shared->size));
                olap = (size_t)olap_d;
                sp = (uint8_t*)buf + (nelmts-1) * src_p->shared->size;
                dp = (uint8_t*)buf + (nelmts-1) * dst_p->shared->size;
                direction = -1;
            }

            /* Get the plist structure */
            if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
                HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID");

            /* Get conversion exception callback property */
            if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0)
                HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback");

            /* Allocate space for order-reversed source buffer */
            src_rev = (uint8_t*)H5MM_calloc(src_p->shared->size);

            /* The conversion loop */
            for (elmtno=0; elmtno<nelmts; elmtno++) {
                /* Set these variables to default */
                except_ret = H5T_CONV_UNHANDLED;
                reverse    = TRUE;

                /*
                 * If the source and destination buffers overlap then use a
                 * temporary buffer for the destination.
                 */
                if (direction>0) {
                    s = sp;
                    d = elmtno<olap ? dbuf : dp;
                } else {
                    s = sp;
                    d = elmtno+olap >= nelmts ? dbuf : dp;
                }
#ifndef NDEBUG
                /* I don't quite trust the overlap calculations yet --rpm */
                if (d==dbuf) {
                    assert ((dp>=sp && dp<sp+src_p->shared->size) ||
                            (sp>=dp && sp<dp+dst_p->shared->size));
                } else {
                    assert ((dp<sp && dp+dst_p->shared->size<=sp) ||
                            (sp<dp && sp+src_p->shared->size<=dp));
                }
#endif
                
                /*
                 * Put the data in little endian order so our loops aren't so
                 * complicated.  We'll do all the conversion stuff assuming
                 * little endian and then we'll fix the order at the end.
                 */
                if (H5T_ORDER_BE==src.order) {
                    half_size = src_p->shared->size/2;
                    for (i=0; i<half_size; i++) {
                        uint8_t tmp = s[src_p->shared->size-(i+1)];
                        s[src_p->shared->size-(i+1)] = s[i];
                        s[i] = tmp;
                    }
                }

                /*
                 * Check for special cases: +0, -0, +Inf, -Inf, NaN
                 */
                if (H5T_bit_find (s, src.u.f.mpos, src.u.f.msize,
                                  H5T_BIT_LSB, TRUE)<0) {
                    if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize,
                                      H5T_BIT_LSB, TRUE)<0) {
                        /* +0 or -0 */
                        H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1);
                        H5T_bit_set (d, dst.u.f.epos, dst.u.f.esize, FALSE);
                        H5T_bit_set (d, dst.u.f.mpos, dst.u.f.msize, FALSE);
                        goto padding;
                    } else if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize,
                                             H5T_BIT_LSB, FALSE)<0) {
                        /* +Inf or -Inf */
                        H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1);
                        H5T_bit_set (d, dst.u.f.epos, dst.u.f.esize, TRUE);
                        H5T_bit_set (d, dst.u.f.mpos, dst.u.f.msize, FALSE);
                        goto padding;
                    }
                } else if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize,
                                         H5T_BIT_LSB, FALSE)<0) {
                    /*
                     * NaN. There are many NaN values, so we just set all bits of
                     * the significand.
                     */
                    H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1);
                    H5T_bit_set (d, dst.u.f.epos, dst.u.f.esize, TRUE);
                    H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, TRUE);
                    goto padding;
                }

                /*
                 * Get the exponent as an unsigned quantity from the section of
                 * the source bit field where it's located.	 Don't worry about
                 * the exponent bias yet.
                 */
                expo = H5T_bit_get_d(s, src.u.f.epos, src.u.f.esize);
                
                /*
                 * Set markers for the source mantissa, excluding the leading `1'
                 * (might be implied).
                 */
                implied = 1;
                mpos = src.u.f.mpos;
                mrsh = 0;
                if (0==expo || H5T_NORM_NONE==src.u.f.norm) {
                    if ((bitno=H5T_bit_find(s, src.u.f.mpos, src.u.f.msize,
                                            H5T_BIT_MSB, TRUE))>0) {
                        msize = bitno;
                    } else if (0==bitno) {
                        msize = 1;
                        H5T_bit_set(s, src.u.f.mpos, 1, FALSE);
                    }
                } else if (H5T_NORM_IMPLIED==src.u.f.norm) {
                    msize = src.u.f.msize;
                } else {
                    assert("normalization method not implemented yet" && 0);
                    HDabort();
                }
                
                /*
                 * The sign for the destination is the same as the sign for the
                 * source in all cases.
                 */
                H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1);

                /*
                 * Calculate the true source exponent by adjusting according to
                 * the source exponent bias.
                 */
                if (0==expo || H5T_NORM_NONE==src.u.f.norm) {
                    bitno = H5T_bit_find(s, src.u.f.mpos, src.u.f.msize,
                                         H5T_BIT_MSB, TRUE);
                    assert(bitno>=0);
                    expo -= (src.u.f.ebias-1) + (src.u.f.msize-bitno);
                } else if (H5T_NORM_IMPLIED==src.u.f.norm) {
                    expo -= src.u.f.ebias;
                } else {
                    assert("normalization method not implemented yet" && 0);
                    HDabort();
                }

                /*
                 * If the destination is not normalized then right shift the
                 * mantissa by one.
                 */
                if (H5T_NORM_NONE==dst.u.f.norm)
                    mrsh++;
                
                /*
                 * Calculate the destination exponent by adding the destination
                 * bias and clipping by the minimum and maximum possible
                 * destination exponent values.
                 */
                expo += dst.u.f.ebias;
                if (expo < -(hssize_t)(dst.u.f.msize)) {
                    /* The exponent is way too small.  Result is zero. */
                    expo = 0;
                    H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE);
                    msize = 0;

                } else if (expo<=0) {
                    /*
                     * The exponent is too small to fit in the exponent field,
                     * but by shifting the mantissa to the right we can
                     * accomodate that value.  The mantissa of course is no
                     * longer normalized.
                     */
                    H5_ASSIGN_OVERFLOW(mrsh,(mrsh+1-expo),hssize_t,size_t);
                    /*mrsh += 1-expo;*/
                    expo = 0;
                    
                } else if (expo>=expo_max) {
                    /*
                     * The exponent is too large to fit in the available region
                     * or it results in the maximum possible value.	 Use positive
                     * or negative infinity instead unless the application
                     * specifies something else.  Before calling the overflow
                     * handler make sure the source buffer we hand it is in the
                     * original byte order.
                     */
                    if(cb_struct.func) { /*If user's exception handler is present, use it*/
                        H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); /*reverse order first*/
                        except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, 
                                src_rev, d, cb_struct.user_data);
                    }
                    
                    if(except_ret == H5T_CONV_UNHANDLED) { 
                        expo = expo_max;
                        H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE);
                        msize = 0;
                    } else if(except_ret == H5T_CONV_ABORT)
                        HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception")
                    else if(except_ret == H5T_CONV_HANDLED) {
                        reverse = FALSE;
                        /*goto next;*/
                        goto padding;
                    }
                }

                /*
                 * If the destination mantissa is smaller than the source
                 * mantissa then round the source mantissa.	 Rounding may cause a
                 * carry in which case the exponent has to be re-evaluated for
                 * overflow.  That is, if `carry' is clear then the implied
                 * mantissa bit is `1', else it is `10' binary.
                 */
                if (msize>0 && mrsh<=dst.u.f.msize && mrsh+msize>dst.u.f.msize) {
                    bitno = (ssize_t)(mrsh+msize - dst.u.f.msize);
                    assert(bitno>=0 && (size_t)bitno<=msize);
                    carry = H5T_bit_inc(s, mpos+bitno-1, 1+msize-bitno);
                    if (carry)
                        implied = 2;
                }
                else
                    carry=0;

                /*
                 * Write the mantissa to the destination
                 */
                if (mrsh>dst.u.f.msize+1) {
                    H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE);
                } else if (mrsh==dst.u.f.msize+1) {
                    H5T_bit_set(d, dst.u.f.mpos+1, dst.u.f.msize-1, FALSE);
                    H5T_bit_set(d, dst.u.f.mpos, 1, TRUE);
                } else if (mrsh==dst.u.f.msize) {
                    H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE);
                    H5T_bit_set_d(d, dst.u.f.mpos, MIN(2, dst.u.f.msize), (hsize_t)implied);
                } else {
                    if (mrsh>0) {
                        H5T_bit_set(d, dst.u.f.mpos+dst.u.f.msize-mrsh, mrsh,
                                    FALSE);
                        H5T_bit_set_d(d, dst.u.f.mpos+dst.u.f.msize-mrsh, 2,
                                      (hsize_t)implied);
                    }
                    if (mrsh+msize>=dst.u.f.msize) {
                        H5T_bit_copy(d, dst.u.f.mpos,
                                     s, (mpos+msize+mrsh-dst.u.f.msize), 
                                     dst.u.f.msize-mrsh);
                    } else {
                        H5T_bit_copy(d, dst.u.f.mpos+dst.u.f.msize-(mrsh+msize),
                                     s, mpos, msize);
                        H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize-(mrsh+msize),
                                    FALSE);
                    }
                }
                    
                /* Write the exponent */
#ifdef OLD_WAY  
/* It appears to be incorrect to increment the exponent when the carry is set -QAK */
                if (carry) {
                    expo++;
                    if (expo>=expo_max) {
                        /*
                         * The exponent is too large to fit in the available
                         * region or it results in the maximum possible value.
                         * Use positive or negative infinity instead unless the
                         * application specifies something else.  Before
                         * calling the overflow handler make sure the source
                         * buffer we hand it is in the original byte order.
                         */
                        if(cb_struct.func) { /*If user's exception handler is present, use it*/
                            H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); /*reverse order first*/
                            except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, 
                                    src_rev, d, cb_struct.user_data);
                        }
                        
                        if(except_ret == H5T_CONV_UNHANDLED) { 
                            expo = expo_max;
                            H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE);
                        } else if(except_ret == H5T_CONV_ABORT)
                            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception")
                        else if(except_ret == H5T_CONV_HANDLED) {
                            reverse = FALSE;
                            /*goto next;*/
                            goto padding;
                        }
                    }
                }
#endif /* OLD_WAY */
                H5_CHECK_OVERFLOW(expo,hssize_t,hsize_t);
                H5T_bit_set_d(d, dst.u.f.epos, dst.u.f.esize, (hsize_t)expo);

            padding:
#ifndef LATER
                /*
                 * Set internal padding areas
                 */
#endif

                /*
                 * Set external padding areas
                 */
                if (dst.offset>0) {
                    assert (H5T_PAD_ZERO==dst.lsb_pad || H5T_PAD_ONE==dst.lsb_pad);
                    H5T_bit_set (d, 0, dst.offset, (hbool_t)(H5T_PAD_ONE==dst.lsb_pad));
                }
                if (dst.offset+dst.prec!=8*dst_p->shared->size) {
                    assert (H5T_PAD_ZERO==dst.msb_pad || H5T_PAD_ONE==dst.msb_pad);
                    H5T_bit_set (d, dst.offset+dst.prec, 8*dst_p->shared->size - (dst.offset+dst.prec),
                         (hbool_t)(H5T_PAD_ONE==dst.msb_pad));
                }

                /*
                 * Put the destination in the correct byte order.  See note at
                 * beginning of loop.
                 */
                if (H5T_ORDER_BE==dst.order && reverse) {
                    half_size = dst_p->shared->size/2;
                    for (i=0; i<half_size; i++) {
                        uint8_t tmp = d[dst_p->shared->size-(i+1)];
                        d[dst_p->shared->size-(i+1)] = d[i];
                        d[i] = tmp;
                    }
                }

                /*
                 * If we had used a temporary buffer for the destination then we
                 * should copy the value to the true destination buffer.
                 */
            /* next: */
                if (d==dbuf)
                    HDmemcpy (dp, d, dst_p->shared->size);
                if (buf_stride) {
                    sp += direction * buf_stride;
                    dp += direction * buf_stride;
                } else {
                    sp += direction * src_p->shared->size;
                    dp += direction * dst_p->shared->size;
                }
            }
            
            H5MM_free(src_rev);

            break;
                
        default:
            HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
    }

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_s_s
 *
 * Purpose:	Convert one fixed-length string type to another.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Robb Matzke
 *		Friday, August	7, 1998
 *
 * Modifications:
 *		Robb Matzke, 1999-06-16
 *		Added support for non-zero strides. If BUF_STRIDE is non-zero
 *		then convert one value at each memory location advancing
 *		BUF_STRIDE bytes each time; otherwise assume both source and
 *		destination values are packed.
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_s_s (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
	      size_t buf_stride, size_t UNUSED bkg_stride, void *buf,
              void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    H5T_t	*src=NULL;		/*source data type		*/
    H5T_t	*dst=NULL;		/*destination data type		*/
    int	direction;		/*direction of traversal	*/
    size_t	elmtno;			/*element number		*/
    size_t	olap;			/*num overlapping elements	*/
    size_t	nchars=0;		/*number of characters copied	*/
    uint8_t	*s, *sp, *d, *dp;	/*src and dst traversal pointers*/
    uint8_t	*dbuf=NULL;		/*temp buf for overlap convers.	*/
    herr_t      ret_value=SUCCEED;       /* Return value */
    
    FUNC_ENTER_NOAPI(H5T_conv_s_s, FAIL);

    switch (cdata->command) {
        case H5T_CONV_INIT:
            if (NULL==(src=H5I_object(src_id)) ||
                    NULL==(dst=H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
            if (8*src->shared->size != src->shared->u.atomic.prec || 8*dst->shared->size != dst->shared->u.atomic.prec)
                HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision");
            if (0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset)
                HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad offset");
            if (H5T_CSET_ASCII != src->shared->u.atomic.u.s.cset || H5T_CSET_ASCII != dst->shared->u.atomic.u.s.cset)
                HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character set");
            if (src->shared->u.atomic.u.s.pad<0 || src->shared->u.atomic.u.s.pad>=H5T_NPAD ||
                    dst->shared->u.atomic.u.s.pad<0 || dst->shared->u.atomic.u.s.pad>=H5T_NPAD)
                HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character padding");
            cdata->need_bkg = H5T_BKG_NO;
            break;

        case H5T_CONV_FREE:
            break;

        case H5T_CONV_CONV:
            /* Get the data types */
            if (NULL==(src=H5I_object(src_id)) ||
                    NULL==(dst=H5I_object(dst_id)))
                HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");

            /*
             * Do we process the values from beginning to end or vice versa? Also,
             * how many of the elements have the source and destination areas
             * overlapping?
             */
            if (src->shared->size==dst->shared->size || buf_stride) {
                /*
                 * When the source and destination are the same size we can do
                 * all the conversions in place.
                 */
                sp = dp = (uint8_t*)buf;
                direction = 1;
                olap = 0;
            } else if (src->shared->size>=dst->shared->size) {
                double olapd = HDceil((double)(dst->shared->size)/
                          (double)(src->shared->size-dst->shared->size));
                olap = (size_t)olapd;
                sp = dp = (uint8_t*)buf;
                direction = 1;
            } else {
                double olapd = HDceil((double)(src->shared->size)/
                          (double)(dst->shared->size-src->shared->size));
                olap = (size_t)olapd;
                sp = (uint8_t*)buf + (nelmts-1) * src->shared->size;
                dp = (uint8_t*)buf + (nelmts-1) * dst->shared->size;
                direction = -1;
            }

            /* Allocate the overlap buffer */
            if (NULL==(dbuf=H5MM_malloc(dst->shared->size)))
                HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for string conversion");
            
            /* The conversion loop. */
            for (elmtno=0; elmtno<nelmts; elmtno++) {

                /*
                 * If the source and destination buffers overlap then use a
                 * temporary buffer for the destination.
                 */
                if (direction>0) {
                    s = sp;
                    d = elmtno<olap ? dbuf : dp;
                } else {
                    s = sp;
                    d = elmtno+olap >= nelmts ? dbuf : dp;
                }
#ifndef NDEBUG
                /* I don't quite trust the overlap calculations yet --rpm */
                if (src->shared->size==dst->shared->size || buf_stride) {
                    assert(s==d);
                } else if (d==dbuf) {
                    assert((dp>=sp && dp<sp+src->shared->size) ||
                       (sp>=dp && sp<dp+dst->shared->size));
                } else {
                    assert((dp<sp && dp+dst->shared->size<=sp) ||
                       (sp<dp && sp+src->shared->size<=dp));
                }
#endif
                
                /* Copy characters from source to destination */
                switch (src->shared->u.atomic.u.s.pad) {
                    case H5T_STR_NULLTERM:
                        for (nchars=0;
                             nchars<dst->shared->size && nchars<src->shared->size && s[nchars];
                             nchars++) {
                            d[nchars] = s[nchars];
                        }
                        break;

                    case H5T_STR_NULLPAD:
                        for (nchars=0;
                             nchars<dst->shared->size && nchars<src->shared->size && s[nchars];
                             nchars++) {
                            d[nchars] = s[nchars];
                        }
                        break;

                    case H5T_STR_SPACEPAD:
                        nchars = src->shared->size;
                        while (nchars>0 && ' '==s[nchars-1])
                            --nchars;
                        nchars = MIN(dst->shared->size, nchars);
                        HDmemcpy(d, s, nchars);
                        break;

                    case H5T_STR_RESERVED_3:
                    case H5T_STR_RESERVED_4:
                    case H5T_STR_RESERVED_5:
                    case H5T_STR_RESERVED_6:
                    case H5T_STR_RESERVED_7:
                    case H5T_STR_RESERVED_8:
                    case H5T_STR_RESERVED_9:
                    case H5T_STR_RESERVED_10:
                    case H5T_STR_RESERVED_11:
                    case H5T_STR_RESERVED_12:
                    case H5T_STR_RESERVED_13:
                    case H5T_STR_RESERVED_14:
                    case H5T_STR_RESERVED_15:
                    case H5T_STR_ERROR:
                        HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "source string padding method not supported");
                }

                /* Terminate or pad the destination */
                switch (dst->shared->u.atomic.u.s.pad) {
                    case H5T_STR_NULLTERM:
                        while (nchars<dst->shared->size)
                            d[nchars++] = '\0';
                        d[dst->shared->size-1] = '\0';
                        break;
                    
                    case H5T_STR_NULLPAD:
                        while (nchars<dst->shared->size)
                            d[nchars++] = '\0';
                        break;
                    
                    case H5T_STR_SPACEPAD:
                        while (nchars<dst->shared->size)
                            d[nchars++] = ' ';
                        break;

                    case H5T_STR_RESERVED_3:
                    case H5T_STR_RESERVED_4:
                    case H5T_STR_RESERVED_5:
                    case H5T_STR_RESERVED_6:
                    case H5T_STR_RESERVED_7:
                    case H5T_STR_RESERVED_8:
                    case H5T_STR_RESERVED_9:
                    case H5T_STR_RESERVED_10:
                    case H5T_STR_RESERVED_11:
                    case H5T_STR_RESERVED_12:
                    case H5T_STR_RESERVED_13:
                    case H5T_STR_RESERVED_14:
                    case H5T_STR_RESERVED_15:
                    case H5T_STR_ERROR:
                        HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination string padding method not supported");
                }

                /*
                 * If we used a temporary buffer for the destination then we
                 * should copy the value to the true destination buffer.
                 */
                if (d==dbuf)
                    HDmemcpy(dp, d, dst->shared->size);
                if (buf_stride) {
                    sp += direction * buf_stride;
                    dp += direction * buf_stride;
                } else {
                    sp += direction * src->shared->size;
                    dp += direction * dst->shared->size;
                }
            }
            break;

        default:
            HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown converson command");
    }

done:
    H5MM_xfree(dbuf);
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_schar_uchar
 *
 * Purpose:	Converts `signed char' to `unsigned char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Monday, November 16, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_schar_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_schar_uchar, FAIL);

    H5T_CONV_su(SCHAR, UCHAR, signed char, unsigned char, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uchar_schar
 *
 * Purpose:	Converts `unsigned char' to `signed char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Monday, November 16, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uchar_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uchar_schar, FAIL);

    H5T_CONV_us(UCHAR, SCHAR, unsigned char, signed char, -, SCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_schar_short
 *
 * Purpose:	Converts `signed char' to `short'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_schar_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_schar_short, FAIL);

    H5T_CONV_sS(SCHAR, SHORT, signed char, short, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_schar_ushort
 *
 * Purpose:	Converts `signed char' to `unsigned short'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_schar_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_schar_ushort, FAIL);

    H5T_CONV_sU(SCHAR, USHORT, signed char, unsigned short, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uchar_short
 *
 * Purpose:	Converts `unsigned char' to `short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uchar_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uchar_short, FAIL);

    H5T_CONV_uS(UCHAR, SHORT, unsigned char, short, -, SHRT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uchar_ushort
 *
 * Purpose:	Converts `unsigned char' to `unsigned short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uchar_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uchar_ushort, FAIL);

    H5T_CONV_uU(UCHAR, USHORT, unsigned char, unsigned short, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_schar_int
 *
 * Purpose:	Converts `signed char' to `int'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_schar_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		   size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                   void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_schar_int, FAIL);

    H5T_CONV_sS(SCHAR, INT, signed char, int, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_schar_uint
 *
 * Purpose:	Converts `signed char' to `unsigned int'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_schar_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_schar_uint, FAIL);

    H5T_CONV_sU(SCHAR, UINT, signed char, unsigned, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uchar_int
 *
 * Purpose:	Converts `unsigned char' to `int'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uchar_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		   size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                   void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uchar_int, FAIL);

    H5T_CONV_uS(UCHAR, INT, unsigned char, int, -, INT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uchar_uint
 *
 * Purpose:	Converts `unsigned char' to `unsigned int'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uchar_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uchar_uint, FAIL);

    H5T_CONV_uU(UCHAR, UINT, unsigned char, unsigned, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_schar_long
 *
 * Purpose:	Converts `signed char' to `long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_schar_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_schar_long, FAIL);

    H5T_CONV_sS(SCHAR, LONG, signed char, long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_schar_ulong
 *
 * Purpose:	Converts `signed char' to `unsigned long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_schar_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_schar_ulong, FAIL);

    H5T_CONV_sU(SCHAR, ULONG, signed char, unsigned long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uchar_long
 *
 * Purpose:	Converts `unsigned char' to `long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uchar_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uchar_long, FAIL);

    H5T_CONV_uS(UCHAR, LONG, unsigned char, long, -, LONG_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uchar_ulong
 *
 * Purpose:	Converts `unsigned char' to `unsigned long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uchar_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uchar_ulong, FAIL);

    H5T_CONV_uU(UCHAR, ULONG, unsigned char, unsigned long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_schar_llong
 *
 * Purpose:	Converts `signed char' to `long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_schar_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_schar_llong, FAIL);

    H5T_CONV_sS(SCHAR, LLONG, signed char, long_long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_schar_ullong
 *
 * Purpose:	Converts `signed char' to `unsigned long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_schar_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_schar_ullong, FAIL);

    H5T_CONV_sU(SCHAR, ULLONG, signed char, unsigned long_long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uchar_llong
 *
 * Purpose:	Converts `unsigned char' to `long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uchar_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uchar_llong, FAIL);

    H5T_CONV_uS(UCHAR, LLONG, unsigned char, long_long, -, LLONG_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uchar_ullong
 *
 * Purpose:	Converts `unsigned char' to `unsigned long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uchar_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uchar_ullong, FAIL);

    H5T_CONV_uU(UCHAR, ULLONG, unsigned char, unsigned long_long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_short_schar
 *
 * Purpose:	Converts `short' to `signed char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_short_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_short_schar, FAIL);

    H5T_CONV_Ss(SHORT, SCHAR, short, signed char, SCHAR_MIN, SCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_short_uchar
 *
 * Purpose:	Converts `short' to `unsigned char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_short_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_short_uchar, FAIL);

    H5T_CONV_Su(SHORT, UCHAR, short, unsigned char, -, UCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ushort_schar
 *
 * Purpose:	Converts `unsigned short' to `signed char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ushort_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ushort_schar, FAIL);
    
    H5T_CONV_Us(USHORT, SCHAR, unsigned short, signed char, -, SCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ushort_uchar
 *
 * Purpose:	Converts `unsigned short' to `unsigned char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ushort_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ushort_uchar, FAIL);

    H5T_CONV_Uu(USHORT, UCHAR, unsigned short, unsigned char, -, UCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_short_ushort
 *
 * Purpose:	Converts `short' to `unsigned short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Monday, November 16, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_short_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_short_ushort, FAIL);
    
    H5T_CONV_su(SHORT, USHORT, short, unsigned short, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ushort_short
 *
 * Purpose:	Converts `unsigned short' to `short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Monday, November 16, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ushort_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ushort_short, FAIL);

    H5T_CONV_us(USHORT, SHORT, unsigned short, short, -, SHRT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_short_int
 *
 * Purpose:	Converts `short' to `int'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_short_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		   size_t nelmts, size_t buf_stride,
                   size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		   hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_short_int, FAIL);

    H5T_CONV_sS(SHORT, INT, short, int, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_short_uint
 *
 * Purpose:	Converts `short' to `unsigned int'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_short_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride,
                    size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		    hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_short_uint, FAIL);

    H5T_CONV_sU(SHORT, UINT, short, unsigned, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ushort_int
 *
 * Purpose:	Converts `unsigned short' to `int'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ushort_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride,
                    size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		    hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ushort_int, FAIL);

    H5T_CONV_uS(USHORT, INT, unsigned short, int, -, INT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ushort_uint
 *
 * Purpose:	Converts `unsigned short' to `unsigned int'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ushort_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ushort_uint, FAIL);

    H5T_CONV_uU(USHORT, UINT, unsigned short, unsigned, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_short_long
 *
 * Purpose:	Converts `short' to `long'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_short_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride,
                    size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		    hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_short_long, FAIL);

    H5T_CONV_sS(SHORT, LONG, short, long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_short_ulong
 *
 * Purpose:	Converts `short' to `unsigned long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_short_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_short_ulong, FAIL);

    H5T_CONV_sU(SHORT, ULONG, short, unsigned long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ushort_long
 *
 * Purpose:	Converts `unsigned short' to `long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ushort_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ushort_long, FAIL);

    H5T_CONV_uS(USHORT, LONG, unsigned short, long, -, LONG_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ushort_ulong
 *
 * Purpose:	Converts `unsigned short' to `unsigned long'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ushort_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ushort_ulong, FAIL);

    H5T_CONV_uU(USHORT, ULONG, unsigned short, unsigned long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_short_llong
 *
 * Purpose:	Converts `short' to `long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_short_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_short_llong, FAIL);

    H5T_CONV_sS(SHORT, LLONG, short, long_long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_short_ullong
 *
 * Purpose:	Converts `short' to `unsigned long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_short_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_short_ullong, FAIL);

    H5T_CONV_sU(SHORT, ULLONG, short, unsigned long_long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ushort_llong
 *
 * Purpose:	Converts `unsigned short' to `long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ushort_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ushort_llong, FAIL);

    H5T_CONV_uS(USHORT, LLONG, unsigned short, long_long, -, LLONG_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ushort_ullong
 *
 * Purpose:	Converts `unsigned short' to `unsigned long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ushort_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		       size_t nelmts, size_t buf_stride,
                       size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                       hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ushort_ullong, FAIL);

    H5T_CONV_uU(USHORT, ULLONG, unsigned short, unsigned long_long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_int_schar
 *
 * Purpose:	Converts `int' to `signed char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_int_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		   size_t nelmts, size_t buf_stride,
                   size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		   hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_int_schar, FAIL);

    H5T_CONV_Ss(INT, SCHAR, int, signed char, SCHAR_MIN, SCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_int_uchar
 *
 * Purpose:	Converts `int' to `unsigned char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_int_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		   size_t nelmts, size_t buf_stride,
                   size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		   hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_int_uchar, FAIL);

    H5T_CONV_Su(INT, UCHAR, int, unsigned char, -, UCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uint_schar
 *
 * Purpose:	Converts `unsigned int' to `signed char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uint_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride,
                    size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		    hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uint_schar, FAIL);

    H5T_CONV_Us(UINT, SCHAR, unsigned, signed char, -, SCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uint_uchar
 *
 * Purpose:	Converts `unsigned int' to `unsigned char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uint_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride,
                    size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		    hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uint_uchar, FAIL);
    
    H5T_CONV_Uu(UINT, UCHAR, unsigned, unsigned char, -, UCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_int_short
 *
 * Purpose:	Converts `int' to `short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_int_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		   size_t nelmts, size_t buf_stride,
                   size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		   hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_int_short, FAIL);

    H5T_CONV_Ss(INT, SHORT, int, short, SHRT_MIN, SHRT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_int_ushort
 *
 * Purpose:	Converts `int' to `unsigned short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_int_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride,
                    size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		    hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_int_ushort, FAIL);

    H5T_CONV_Su(INT, USHORT, int, unsigned short, -, USHRT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uint_short
 *
 * Purpose:	Converts `unsigned int' to `short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uint_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride,
                    size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		    hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uint_short, FAIL);

    H5T_CONV_Us(UINT, SHORT, unsigned, short, -, SHRT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uint_ushort
 *
 * Purpose:	Converts `unsigned int' to `unsigned short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uint_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uint_ushort, FAIL);

    H5T_CONV_Uu(UINT, USHORT, unsigned, unsigned short, -, USHRT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_int_uint
 *
 * Purpose:	Converts `int' to `unsigned int'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Monday, November 16, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_int_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		  size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                  void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_int_uint, FAIL);

    H5T_CONV_su(INT, UINT, int, unsigned, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uint_int
 *
 * Purpose:	Converts `unsigned int' to `int'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Monday, November 16, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uint_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		  size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                  void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uint_int, FAIL);

    H5T_CONV_us(UINT, INT, unsigned, int, -, INT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_int_long
 *
 * Purpose:	Converts `int' to `long'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_int_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		  size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                  void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_int_long, FAIL);

    H5T_CONV_sS(INT, LONG, int, long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_int_ulong
 *
 * Purpose:	Converts `int' to `unsigned long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_int_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		   size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                   void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_int_ulong, FAIL);

    H5T_CONV_sU(INT, LONG, int, unsigned long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uint_long
 *
 * Purpose:	Converts `unsigned int' to `long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uint_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		   size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                   void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uint_long, FAIL);

    H5T_CONV_uS(UINT, LONG, unsigned, long, -, LONG_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uint_ulong
 *
 * Purpose:	Converts `unsigned int' to `unsigned long'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uint_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uint_ulong, FAIL);

    H5T_CONV_uU(UINT, ULONG, unsigned, unsigned long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_int_llong
 *
 * Purpose:	Converts `int' to `long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_int_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		   size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                   void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_int_llong, FAIL);

    H5T_CONV_sS(INT, LLONG, int, long_long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_int_ullong
 *
 * Purpose:	Converts `int' to `unsigned long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_int_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_int_ullong, FAIL);

    H5T_CONV_sU(INT, ULLONG, int, unsigned long_long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uint_llong
 *
 * Purpose:	Converts `unsigned int' to `long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uint_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uint_llong, FAIL);

    H5T_CONV_uS(UINT, LLONG, unsigned, long_long, -, LLONG_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_uint_ullong
 *
 * Purpose:	Converts `unsigned int' to `unsigned long_long'
 *
 * Return:	Success:	Non-negative
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_uint_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_uint_ullong, FAIL);

    H5T_CONV_uU(UINT, ULLONG, unsigned, unsigned long_long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_long_schar
 *
 * Purpose:	Converts `long' to `signed char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_long_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_long_schar, FAIL);

    H5T_CONV_Ss(LONG, SCHAR, long, signed char, SCHAR_MIN, SCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_long_uchar
 *
 * Purpose:	Converts `long' to `unsigned char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_long_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_long_uchar, FAIL);

    H5T_CONV_Su(LONG, UCHAR, long, unsigned char, -, UCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ulong_schar
 *
 * Purpose:	Converts `unsigned long' to `signed char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ulong_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ulong_schar, FAIL);

    H5T_CONV_Us(ULONG, SCHAR, unsigned long, signed char, -, SCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ulong_uchar
 *
 * Purpose:	Converts `unsigned long' to `unsigned char'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ulong_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ulong_uchar, FAIL);

    H5T_CONV_Uu(ULONG, UCHAR, unsigned long, unsigned char, -, UCHAR_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_long_short
 *
 * Purpose:	Converts `long' to `short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_long_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_long_short, FAIL);

    H5T_CONV_Ss(LONG, SHORT, long, short, SHRT_MIN, SHRT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_long_ushort
 *
 * Purpose:	Converts `long' to `unsigned short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_long_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		     size_t nelmts, size_t buf_stride,
                     size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
		     hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_long_ushort, FAIL);

    H5T_CONV_Su(LONG, USHORT, long, unsigned short, -, USHRT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ulong_short
 *
 * Purpose:	Converts `unsigned long' to `short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ulong_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                     void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ulong_short, FAIL);

    H5T_CONV_Us(ULONG, SHORT, unsigned long, short, -, SHRT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ulong_ushort
 *
 * Purpose:	Converts `unsigned long' to `unsigned short'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ulong_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		      size_t nelmts, size_t buf_stride,
                      size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
                      hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ulong_ushort, FAIL);

    H5T_CONV_Uu(ULONG, USHORT, unsigned long, unsigned short, -, USHRT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_long_int
 *
 * Purpose:	Converts `long' to `int'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_long_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		  size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                  void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_long_int, FAIL);

    H5T_CONV_Ss(LONG, INT, long, int, INT_MIN, INT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_long_uint
 *
 * Purpose:	Converts `long' to `unsigned int'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_long_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		   size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                   void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_long_uint, FAIL);

    H5T_CONV_Su(LONG, UINT, long, unsigned, -, UINT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ulong_int
 *
 * Purpose:	Converts `unsigned long' to `int'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ulong_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		   size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                   void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ulong_int, FAIL);

    H5T_CONV_Us(ULONG, INT, unsigned long, int, -, INT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ulong_uint
 *
 * Purpose:	Converts `unsigned long' to `unsigned int'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Friday, November 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ulong_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ulong_uint, FAIL);

    H5T_CONV_Uu(ULONG, UINT, unsigned long, unsigned, -, UINT_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_long_ulong
 *
 * Purpose:	Converts `long' to `unsigned long'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Monday, November 16, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_long_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_long_ulong, FAIL);

    H5T_CONV_su(LONG, ULONG, long, unsigned long, -, -);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_ulong_long
 *
 * Purpose:	Converts `unsigned long' to `long'
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Robb Matzke
 *		Monday, November 16, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5T_conv_ulong_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
		    size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride,
                    void *buf, void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5T_conv_ulong_long, FAIL);

    H5T_CONV_us(ULONG, LONG, unsigned long, long, -, LONG_MAX);

done:
    FUNC_LEAVE_NOAPI(ret_value);
}


/*-------------------------------------------------------------------------
 * Function:	H5T_conv_long_llong
 *