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 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 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 9566 9567 9568 9569 9570 9571 9572 9573 9574 9575 9576 9577 9578 9579 9580 9581 9582 9583 9584 9585 9586 9587 9588 9589 9590 9591 9592 9593 9594 9595 9596 9597 9598 9599 9600 9601 9602 9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 9617 9618 9619 9620 9621 9622 9623 9624 9625 9626 9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 9642 9643 9644 9645 9646 9647 9648 9649 9650 9651 9652 9653 9654 9655 9656 9657 9658 9659 9660 9661 9662 9663 9664 9665 9666 9667 9668 9669 9670 9671 9672 9673 9674 9675 9676 9677 9678 9679 9680 9681 9682 9683 9684 9685 9686 9687 9688 9689 9690 9691 9692 9693 9694 9695 9696 9697 9698 9699 9700 9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711 9712 9713 9714 9715 9716 9717 9718 9719 9720 9721 9722 9723 9724 9725 9726 9727 9728 9729 9730 9731 9732 9733 9734 9735 9736 9737 9738 9739 9740 9741 9742 9743 9744 9745 9746 9747 9748 9749 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 9780 9781 9782 9783 9784 9785 9786 9787 9788 9789 9790 9791 9792 9793 9794 9795 9796 9797 9798 9799 9800 9801 9802 9803 9804 9805 9806 9807 9808 9809 9810 9811 9812 9813 9814 9815 9816 9817 9818 9819 9820 9821 9822 9823 9824 9825 9826 9827 9828 9829 9830 9831 9832 9833 9834 9835 9836 9837 9838 9839 9840 9841 9842 9843 9844 9845 9846 9847 9848 9849 9850 9851 9852 9853 9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885 9886 9887 9888 9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961 9962 9963 9964 9965 9966 9967 9968 9969 9970 9971 9972 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020 10021 10022 10023 10024 10025 10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 10036 10037 10038 10039 10040 10041 10042 10043 10044 10045 10046 10047 10048 10049 10050 10051 10052 10053 10054 10055 10056 10057 10058 10059 10060 10061 10062 10063 10064 10065 10066 10067 10068 10069 10070 10071 10072 10073 10074 10075 10076 10077 10078 10079 10080 10081 10082 10083 10084 10085 10086 10087 10088 10089 10090 10091 10092 10093 10094 10095 10096 10097 10098 10099 10100 10101 10102 10103 10104 10105 10106 10107 10108 10109 10110 10111 10112 10113 10114 10115 10116 10117 10118 10119 10120 10121 10122 10123 10124 10125 10126 10127 10128 10129 10130 10131 10132 10133 10134 10135 10136 10137 10138 10139 10140 10141 10142 10143 10144 10145 10146 10147 10148 10149 10150 10151 10152 10153 10154 10155 10156 10157 10158 10159 10160 10161 10162 10163 10164 10165 10166 10167 10168 10169 10170 10171 10172 10173 10174 10175 10176 10177 10178 10179 10180 10181 10182 10183 10184 10185 10186 10187 10188 10189 10190 10191 10192 10193 10194 10195 10196 10197 10198 10199 10200 10201 10202 10203 10204 10205 10206 10207 10208 10209 10210 10211 10212 10213 10214 10215 10216 10217 10218 10219 10220 10221 10222 10223 10224 10225 10226 10227 10228 10229 10230 10231 10232 10233 10234 10235 10236 10237 10238 10239 10240 10241 10242 10243 10244 10245 10246 10247 10248 10249 10250 10251 10252 10253 10254 10255 10256 10257 10258 10259 10260 10261 10262 10263 10264 10265 10266 10267 10268 10269 10270 10271 10272 10273 10274 10275 10276 10277 10278 10279 10280 10281 10282 10283 10284 10285 10286 10287 10288 10289 10290 10291 10292 10293 10294 10295 10296 10297 10298 10299 10300 10301 10302 10303 10304 10305 10306 10307 10308 10309 10310 10311 10312 10313 10314 10315 10316 10317 10318 10319 10320 10321 10322 10323 10324 10325 10326 10327 10328 10329 10330 10331 10332 10333 10334 10335 10336 10337 10338 10339 10340 10341 10342 10343 10344 10345 10346 10347 10348 10349 10350 10351 10352 10353 10354 10355 10356 10357 10358 10359 10360 10361 10362 10363 10364 10365 10366 10367 10368 10369 10370 10371 10372 10373 10374 10375 10376 10377 10378 10379 10380 10381 10382 10383 10384 10385 10386 10387 10388 10389 10390 10391 10392 10393 10394 10395 10396 10397 10398 10399 10400 10401 10402 10403 10404 10405 10406 10407 10408 10409 10410 10411 10412 10413 10414 10415 10416 10417 10418 10419 10420 10421 10422 10423 10424 10425 10426 10427 10428 10429 10430 10431 10432 10433 10434 10435 10436 10437 10438 10439 10440 10441 10442 10443 10444 10445 10446 10447 10448 10449 10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 10464 10465 10466 10467 10468 10469 10470 10471 10472 10473 10474 10475 10476 10477 10478 10479 10480 10481 10482 10483 10484 10485 10486 10487 10488 10489 10490 10491 10492 10493 10494 10495 10496 10497 10498 10499 10500 10501 10502 10503 10504 10505 10506 10507 10508 10509 10510 10511 10512 10513 10514 10515 10516 10517 10518 10519 10520 10521 10522 10523 10524 10525 10526 10527 10528 10529 10530 10531 10532 10533 10534 10535 10536 10537 10538 10539 10540 10541 10542 10543 10544 10545 10546 10547 10548 10549 10550 10551 10552 10553 10554 10555 10556 10557 10558 10559 10560 10561 10562 10563 10564 10565 10566 10567 10568 10569 10570 10571 10572 10573 10574 10575 10576 10577 10578 10579 10580 10581 10582 10583 10584 10585 10586 10587 10588 10589 10590 10591 10592 10593 10594 10595 10596 10597 10598 10599 10600 10601 10602 10603 10604 10605 10606 10607 10608 10609 10610 10611 10612 10613 10614 10615 10616 10617 10618 10619 10620 10621 10622 10623 10624 10625 10626 10627 10628 10629 10630 10631 10632 10633 10634 10635 10636 10637 10638 10639 10640 10641 10642 10643 10644 10645 10646 10647 10648 10649 10650 10651 10652 10653 10654 10655 10656 10657 10658 10659 10660 10661 10662 10663 10664 10665 10666 10667 10668 10669 10670 10671 10672 10673 10674 10675 10676 10677 10678 10679 10680 10681 10682 10683 10684 10685 10686 10687 10688 10689 10690 10691 10692 10693 10694 10695 10696 10697 10698 10699 10700 10701 10702 10703 10704 10705 10706 10707 10708 10709 10710 10711 10712 10713 10714 10715 10716 10717 10718 10719 10720 10721 10722 10723 10724 10725 10726 10727 10728 10729 10730 10731 10732 10733 10734 10735 10736 10737 10738 10739 10740 10741 10742 10743 10744 10745 10746 10747 10748 10749 10750 10751 10752 10753 10754 10755 10756 10757 10758 10759 10760 10761 10762 10763 10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 10776 10777 10778 10779 10780 10781 10782 10783 10784 10785 10786 10787 10788 10789 10790 10791 10792 10793 10794 10795 10796 10797 10798 10799 10800 10801 10802 10803 10804 10805 10806 10807 10808 10809 10810 10811 10812 10813 10814 10815 10816 10817 10818 10819 10820 10821 10822 10823 10824 10825 10826 10827 10828 10829 10830 10831 10832 10833 10834 10835 10836 10837 10838 10839 10840 10841 10842 10843 10844 10845 10846 10847 10848 10849 10850 10851 10852 10853 10854 10855 10856 10857 10858 10859 10860 10861 10862 10863 10864 10865 10866 10867 10868 10869 10870 10871 10872 10873 10874 10875 10876 10877 10878 10879 10880 10881 10882 10883 10884 10885 10886 10887 10888 10889 10890 10891 10892 10893 10894 10895 10896 10897 10898 10899 10900 10901 10902 10903 10904 10905 10906 10907 10908 10909 10910 10911 10912 10913 10914 10915 10916 10917 10918 10919 10920 10921 10922 10923 10924 10925 10926 10927 10928 10929 10930 10931 10932 10933 10934 10935 10936 10937 10938 10939 10940 10941 10942 10943 10944 10945 10946 10947 10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 10962 10963 10964 10965 10966 10967 10968 10969 10970 10971 10972 10973 10974 10975 10976 10977 10978 10979 10980 10981 10982 10983 10984 10985 10986 10987 10988 10989 10990 10991 10992 10993 10994 10995 10996 10997 10998 10999 11000 11001 11002 11003 11004 11005 11006 11007 11008 11009 11010 11011 11012 11013 11014 11015 11016 11017 11018 11019 11020 11021 11022 11023 11024 11025 11026 11027 11028 11029 11030 11031 11032 11033 11034 11035 11036 11037 11038 11039 11040 11041 11042 11043 11044 11045 11046 11047 11048 11049 11050 11051 11052 11053 11054 11055 11056 11057 11058 11059 11060 11061 11062 11063 11064 11065 11066 11067 11068 11069 11070 11071 11072 11073 11074 11075 11076 11077 11078 11079 11080 11081 11082 11083 11084 11085 11086 11087 11088 11089 11090 11091 11092 11093 11094 11095 11096 11097 11098 11099 11100 11101 11102 11103 11104 11105 11106 11107 11108 11109 11110 11111 11112 11113 11114 11115 11116 11117 11118 11119 11120 11121 11122 11123 11124 11125 11126 11127 11128 11129 11130 11131 11132 11133 11134 11135 11136 11137 11138 11139 11140 11141 11142 11143 11144 11145 11146 11147 11148 11149 11150 11151 11152 11153 11154 11155 11156 11157 11158 11159 11160 11161 11162 11163 11164 11165 11166 11167 11168 11169 11170 11171 11172 11173 11174 11175 11176 11177 11178 11179 11180 11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 11192 11193 11194 11195 11196 11197 11198 11199 11200 11201 11202 11203 11204 11205 11206 11207 11208 11209 11210 11211 11212 11213 11214 11215 11216 11217 11218 11219 11220 11221 11222 11223 11224 11225 11226 11227 11228 11229 11230 11231 11232 11233 11234 11235 11236 11237 11238 11239 11240 11241 11242 11243 11244 11245 11246 11247 11248 11249 11250 11251 11252 11253 11254 11255 11256 11257 11258 11259 11260 11261 11262 11263 11264 11265 11266 11267 11268 11269 11270 11271 11272 11273 11274 11275 11276 11277 11278 11279 11280 11281 11282 11283 11284 11285 11286 11287 11288 11289 11290 11291 11292 11293 11294 11295 11296 11297 11298 11299 11300 11301 11302 11303 11304 11305 11306 11307 11308 11309 11310 11311 11312 11313 11314 11315 11316 11317 11318 11319 11320 11321 11322 11323 11324 11325 11326 11327 11328 11329 11330 11331 11332 11333 11334 11335 11336 11337 11338 11339 11340 11341 11342 11343 11344 11345 11346 11347 11348 11349 11350 11351 11352 11353 11354 11355 11356 11357 11358 11359 11360 11361 11362 11363 11364 11365 11366 11367 11368 11369 11370 11371 11372 11373 11374 11375 11376 11377 11378 11379 11380 11381 11382 11383 11384 11385 11386 11387 11388 11389 11390 11391 11392 11393 11394 11395 11396 11397 11398 11399 11400 11401 11402 11403 11404 11405 11406 11407 11408 11409 11410 11411 11412 11413 11414 11415 11416 11417 11418 11419 11420 11421 11422 11423 11424 11425 11426 11427 11428 11429 11430 11431 11432 11433 11434 11435 11436 11437 11438 11439 11440 11441 11442 11443 11444 11445 11446 11447 11448 11449 11450 11451 11452 11453 11454 11455 11456 11457 11458 11459 11460 11461 11462 11463 11464 11465 11466 11467 11468 11469 11470 11471 11472 11473 11474 11475 11476 11477 11478 11479 11480 11481 11482 11483 11484 11485 11486 11487 11488 11489 11490 11491 11492 11493 11494 11495 11496 11497 11498 11499 11500 11501 11502 11503 11504 11505 11506 11507 11508 11509 11510 11511 11512 11513 11514 11515 11516 11517 11518 11519 11520 11521 11522 11523 11524 11525 11526 11527 11528 11529 11530 11531 11532 11533 11534 11535 11536 11537 11538 11539 11540 11541 11542 11543 11544 11545 11546 11547 11548 11549 11550 11551 11552 11553 11554 11555 11556 11557 11558 11559 11560 11561 11562 11563 11564 11565 11566 11567 11568 11569 11570 11571 11572 11573 11574 11575 11576 11577 11578 11579 11580 11581 11582 11583 11584 11585 11586 11587 11588 11589 11590 11591 11592 11593 11594 11595 11596 11597 11598 11599 11600 11601 11602 11603 11604 11605 11606 11607 11608 11609 11610 11611 11612 11613 11614 11615 11616 11617 11618 11619 11620 11621 11622 11623 11624 11625 11626 11627 11628 11629 11630 11631 11632 11633 11634 11635 11636 11637 11638 11639 11640 11641 11642 11643 11644 11645 11646 11647 11648 11649 11650 11651 11652 11653 11654 11655 11656 11657 11658 11659 11660 11661 11662 11663 11664 11665 11666 11667 11668 11669 11670 11671 11672 11673 11674 11675 11676 11677 11678 11679 11680 11681 11682 11683 11684 11685 11686 11687 11688 11689 11690 11691 11692 11693 11694 11695 11696 11697 11698 11699 11700 11701 11702 11703 11704 11705 11706 11707 11708 11709 11710 11711 11712 11713 11714 11715 11716 11717 11718 11719 11720 11721 11722 11723 11724 11725 11726 11727 11728 11729 11730 11731 11732 11733 11734 11735 11736 11737 11738 11739 11740 11741 11742 11743 11744 11745 11746 11747 11748 11749 11750 11751 11752 11753 11754 11755 11756 11757 11758 11759 11760 11761 11762 11763 11764 11765 11766 11767 11768 11769 11770 11771 11772 11773 11774 11775 11776 11777 11778 11779 11780 11781 11782 11783 11784 11785 11786 11787 11788 11789 11790 11791 11792 11793 11794 11795 11796 11797 11798 11799 11800 11801 11802 11803 11804 11805 11806 11807 11808 11809 11810 11811 11812 11813 11814 11815 11816 11817 11818 11819 11820 11821 11822 11823 11824 11825 11826 11827 11828 11829 11830 11831 11832 11833 11834 11835 11836 11837 11838 11839 11840 11841 11842 11843 11844 11845 11846 11847 11848 11849 11850 11851 11852 11853 11854 11855 11856 11857 11858 11859 11860 11861 11862 11863 11864 11865 11866 11867 11868 11869 11870 11871 11872 11873 11874 11875 11876 11877 11878 11879 11880 11881 11882 11883 11884 11885 11886 11887 11888 11889 11890 11891 11892 11893 11894 11895 11896 11897 11898 11899 11900 11901 11902 11903 11904 11905 11906 11907 11908 11909 11910 11911 11912 11913 11914 11915 11916 11917 11918 11919 11920 11921 11922 11923 11924 11925 11926 11927 11928 11929 11930 11931 11932 11933 11934 11935 11936 11937 11938 11939 11940 11941 11942 11943 11944 11945 11946 11947 11948 11949 11950 11951 11952 11953 11954 11955 11956 11957 11958 11959 11960 11961 11962 11963 11964 11965 11966 11967 11968 11969 11970 11971 11972 11973 11974 11975 11976 11977 11978 11979 11980 11981 11982 11983 11984 11985 11986 11987 11988 11989 11990 11991 11992 11993 11994 11995 11996 11997 11998 11999 12000 12001 12002 12003 12004 12005 12006 12007 12008 12009 12010 12011 12012 12013 12014 12015 12016 12017 12018 12019 12020 12021 12022 12023 12024 12025 12026 12027 12028 12029 12030 12031 12032 12033 12034 12035 12036 12037 12038 12039 12040 12041 12042 12043 12044 12045 12046 12047 12048 12049 12050 12051 12052 12053 12054 12055 12056 12057 12058 12059 12060 12061 12062 12063 12064 12065 12066 12067 12068 12069 12070 12071 12072 12073 12074 12075 12076 12077 12078 12079 12080 12081 12082 12083 12084 12085 12086 12087 12088 12089 12090 12091 12092 12093 12094 12095 12096 12097 12098 12099 12100 12101 12102 12103 12104 12105 12106 12107 12108 12109 12110 12111 12112 12113 12114 12115 12116 12117 12118 12119 12120 12121 12122 12123 12124 12125 12126 12127 12128 12129 12130 12131 12132 12133 12134 12135 12136 12137 12138 12139 12140 12141 12142 12143 12144 12145 12146 12147 12148 12149 12150 12151 12152 12153 12154 12155 12156 12157 12158 12159 12160 12161 12162 12163 12164 12165 12166 12167 12168 12169 12170 12171 12172 12173 12174 12175 12176 12177 12178 12179 12180 12181 12182 12183 12184 12185 12186 12187 12188 12189 12190 12191 12192 12193 12194 12195 12196 12197 12198 12199 12200 12201 12202 12203 12204 12205 12206 12207 12208 12209 12210 12211 12212 12213 12214 12215 12216 12217 12218 12219 12220 12221 12222 12223 12224 12225 12226 12227 12228 12229 12230 12231 12232 12233 12234 12235 12236 12237 12238 12239 12240 12241 12242 12243 12244 12245 12246 12247 12248 12249 12250 12251 12252 12253 12254 12255 12256 12257 12258 12259 12260 12261 12262 12263 12264 12265 12266 12267 12268 12269 12270 12271 12272 12273 12274 12275 12276 12277 12278 12279 12280 12281 12282 12283 12284 12285 12286 12287 12288 12289 12290 12291 12292 12293 12294 12295 12296 12297 12298 12299 12300 12301 12302 12303 12304 12305 12306 12307 12308 12309 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320 12321 12322 12323 12324 12325 12326 12327 12328 12329 12330 12331 12332 12333 12334 12335 12336 12337 12338 12339 12340 12341 12342 12343 12344 12345 12346 12347 12348 12349 12350 12351 12352 12353 12354 12355 12356 12357 12358 12359 12360 12361 12362 12363 12364 12365 12366 12367 12368 12369 12370 12371 12372 12373 12374 12375 12376 12377 12378 12379 12380 12381 12382 12383 12384 12385 12386 12387 12388 12389 12390 12391 12392 12393 12394 12395 12396 12397 12398 12399 12400 12401 12402 12403 12404 12405 12406 12407 12408 12409 12410 12411 12412 12413 12414 12415 12416 12417 12418 12419 12420 12421 12422 12423 12424 12425 12426 12427 12428 12429 12430 12431 12432 12433 12434 12435 12436 12437 12438 12439 12440 12441 12442 12443 12444 12445 12446 12447 12448 12449 12450 12451 12452 12453 12454 12455 12456 12457 12458 12459 12460 12461 12462 12463 12464 12465 12466 12467 12468 12469 12470 12471 12472 12473 12474 12475 12476 12477 12478 12479 12480 12481 12482 12483 12484 12485 12486 12487 12488 12489 12490 12491 12492 12493 12494 12495 12496 12497 12498 12499 12500 12501 12502 12503 12504 12505 12506 12507 12508 12509 12510 12511 12512 12513 12514 12515 12516 12517 12518 12519 12520 12521 12522 12523 12524 12525 12526 12527 12528 12529 12530 12531 12532 12533 12534 12535 12536 12537 12538 12539 12540 12541 12542 12543 12544 12545 12546 12547 12548 12549 12550 12551 12552 12553 12554 12555 12556 12557 12558 12559 12560 12561 12562 12563 12564 12565 12566 12567 12568 12569 12570 12571 12572 12573 12574 12575 12576 12577 12578 12579 12580 12581 12582 12583 12584 12585 12586 12587 12588 12589 12590 12591 12592 12593 12594 12595 12596 12597 12598 12599 12600 12601 12602 12603 12604 12605 12606 12607 12608 12609 12610 12611 12612 12613 12614 12615 12616 12617 12618 12619 12620 12621 12622 12623 12624 12625 12626 12627 12628 12629 12630 12631 12632 12633 12634 12635 12636 12637 12638 12639 12640 12641 12642 12643 12644 12645 12646 12647 12648 12649 12650 12651 12652 12653 12654 12655 12656 12657 12658 12659 12660 12661 12662 12663 12664 12665 12666 12667 12668 12669 12670 12671 12672 12673 12674 12675 12676 12677 12678 12679 12680 12681 12682 12683 12684 12685 12686 12687 12688 12689 12690 12691 12692 12693 12694 12695 12696 12697 12698 12699 12700 12701 12702 12703 12704 12705 12706 12707 12708 12709 12710 12711 12712 12713 12714 12715 12716 12717 12718 12719 12720 12721 12722 12723 12724 12725 12726 12727 12728 12729 12730 12731 12732 12733 12734 12735 12736 12737 12738 12739 12740 12741 12742 12743 12744 12745 12746 12747 12748 12749 12750 12751 12752 12753 12754 12755 12756 12757 12758 12759 12760 12761 12762 12763 12764 12765 12766 12767 12768 12769 12770 12771 12772 12773 12774 12775 12776 12777 12778 12779 12780 12781 12782 12783 12784 12785 12786 12787 12788 12789 12790 12791 12792 12793 12794 12795 12796 12797 12798 12799 12800 12801 12802 12803 12804 12805 12806 12807 12808 12809 12810 12811 12812 12813 12814 12815 12816 12817 12818 12819 12820 12821 12822 12823 12824 12825 12826 12827 12828 12829 12830 12831 12832 12833 12834 12835 12836 12837 12838 12839 12840 12841 12842 12843 12844 12845 12846 12847 12848 12849 12850 12851 12852 12853 12854 12855 12856 12857 12858 12859 12860 12861 12862 12863 12864 12865 12866 12867 12868 12869 12870 12871 12872 12873 12874 12875 12876 12877 12878 12879 12880 12881 12882 12883 12884 12885 12886 12887 12888 12889 12890 12891 12892 12893 12894 12895 12896 12897 12898 12899 12900 12901 12902 12903 12904 12905 12906 12907 12908 12909 12910 12911 12912 12913 12914 12915 12916 12917 12918 12919 12920 12921 12922 12923 12924 12925 12926 12927 12928 12929 12930 12931 12932 12933 12934 12935 12936 12937 12938 12939 12940 12941 12942 12943 12944 12945 12946 12947 12948 12949 12950 12951 12952 12953 12954 12955 12956 12957 12958 12959 12960 12961 12962 12963 12964 12965 12966 12967 12968 12969 12970 12971 12972 12973 12974 12975 12976 12977 12978 12979 12980 12981 12982 12983 12984 12985 12986 12987 12988 12989 12990 12991 12992 12993 12994 12995 12996 12997 12998 12999 13000 13001 13002 13003 13004 13005 13006 13007 13008 13009 13010 13011 13012 13013 13014 13015 13016 13017 13018 13019 13020 13021 13022 13023 13024 13025 13026 13027 13028 13029 13030 13031 13032 13033 13034 13035 13036 13037 13038 13039 13040 13041 13042 13043 13044 13045 13046 13047 13048 13049 13050 13051 13052 13053 13054 13055 13056 13057 13058 13059 13060 13061 13062 13063 13064 13065 13066 13067 13068 13069 13070 13071 13072 13073 13074 13075 13076 13077 13078 13079 13080 13081 13082 13083 13084 13085 13086 13087 13088 13089 13090 13091 13092 13093 13094 13095 13096 13097 13098 13099 13100 13101 13102 13103 13104 13105 13106 13107 13108 13109 13110 13111 13112 13113 13114 13115 13116 13117 13118 13119 13120 13121 13122 13123 13124 13125 13126 13127 13128 13129 13130 13131 13132 13133 13134 13135 13136 13137 13138 13139 13140 13141 13142 13143 13144 13145 13146 13147 13148 13149 13150 13151 13152 13153 13154 13155 13156 13157 13158 13159 13160 13161 13162 13163 13164 13165 13166 13167 13168 13169 13170 13171 13172 13173 13174 13175 13176 13177 13178 13179 13180 13181 13182 13183 13184 13185 13186 13187 13188 13189 13190 13191 13192 13193 13194 13195 13196 13197 13198 13199 13200 13201 13202 13203 13204 13205 13206 13207 13208 13209 13210 13211 13212 13213 13214 13215 13216 13217 13218 13219 13220 13221 13222 13223 13224 13225 13226 13227 13228 13229 13230 13231 13232 13233 13234 13235 13236 13237 13238 13239 13240 13241 13242 13243 13244 13245 13246 13247 13248 13249 13250 13251 13252 13253 13254 13255 13256 13257 13258 13259 13260 13261 13262 13263 13264 13265 13266 13267 13268 13269 13270 13271 13272 13273 13274 13275 13276 13277 13278 13279 13280 13281 13282 13283 13284 13285 13286 13287 13288 13289 13290 13291 13292 13293 13294 13295 13296 13297 13298 13299 13300 13301 13302 13303 13304 13305 13306 13307 13308 13309 13310 13311 13312 13313 13314 13315 13316 13317 13318 13319 13320 13321 13322 13323 13324 13325 13326 13327 13328 13329 13330 13331 13332 13333 13334 13335 13336 13337 13338 13339 13340 13341 13342 13343 13344 13345 13346 13347 13348 13349 13350 13351 13352 13353 13354 13355 13356 13357 13358 13359 13360 13361 13362 13363 13364 13365 13366 13367 13368 13369 13370 13371 13372 13373 13374 13375 13376 13377 13378 13379 13380 13381 13382 13383 13384 13385 13386 13387 13388 13389 13390 13391 13392 13393 13394 13395 13396 13397 13398 13399 13400 13401 13402 13403 13404 13405 13406 13407 13408 13409 13410 13411 13412 13413 13414 13415 13416 13417 13418 13419 13420 13421 13422 13423 13424 13425 13426 13427 13428 13429 13430 13431 13432 13433 13434 13435 13436 13437 13438 13439 13440 13441 13442 13443 13444 13445 13446 13447 13448 13449 13450 13451 13452 13453 13454 13455 13456 13457 13458 13459 13460 13461 13462 13463 13464 13465 13466 13467 13468 13469 13470 13471 13472 13473 13474 13475 13476 13477 13478 13479 13480 13481 13482 13483 13484 13485 13486 13487 13488 13489 13490 13491 13492 13493 13494 13495 13496 13497 13498 13499 13500 13501 13502 13503 13504 13505 13506 13507 13508 13509 13510 13511 13512 13513 13514 13515 13516 13517 13518 13519 13520 13521 13522 13523 13524 13525 13526 13527 13528 13529 13530 13531 13532 13533 13534 13535 13536 13537 13538 13539 13540 13541 13542 13543 13544 13545 13546 13547 13548 13549 13550 13551 13552 13553 13554 13555 13556 13557 13558 13559 13560 13561 13562 13563 13564 13565 13566 13567 13568 13569 13570 13571 13572 13573 13574 13575 13576 13577 13578 13579 13580 13581 13582 13583 13584 13585 13586 13587 13588 13589 13590 13591 13592 13593 13594 13595 13596 13597 13598 13599 13600 13601 13602 13603 13604 13605 13606 13607 13608 13609 13610 13611 13612 13613 13614 13615 13616 13617 13618 13619 13620 13621 13622 13623 13624 13625 13626 13627 13628 13629 13630 13631 13632 13633 13634 13635 13636 13637 13638 13639 13640 13641 13642 13643 13644 13645 13646 13647 13648 13649 13650 13651 13652 13653 13654 13655 13656 13657 13658 13659 13660 13661 13662 13663 13664 13665 13666 13667 13668 13669 13670 13671 13672 13673 13674 13675 13676 13677 13678 13679 13680 13681 13682 13683 13684 13685 13686 13687 13688 13689 13690 13691 13692 13693 13694 13695 13696 13697 13698 13699 13700 13701 13702 13703 13704 13705 13706 13707 13708 13709 13710 13711 13712 13713 13714 13715 13716 13717 13718 13719 13720 13721 13722 13723 13724 13725 13726 13727 13728 13729 13730 13731 13732 13733 13734 13735 13736 13737 13738 13739 13740 13741 13742 13743 13744 13745 13746 13747 13748 13749 13750 13751 13752 13753 13754 13755 13756 13757 13758 13759 13760 13761 13762 13763 13764 13765 13766 13767 13768 13769 13770 13771 13772 13773 13774 13775 13776 13777 13778 13779 13780 13781 13782 13783 13784 13785 13786 13787 13788 13789 13790 13791 13792 13793 13794 13795 13796 13797 13798 13799 13800 13801 13802 13803 13804 13805 13806 13807 13808 13809 13810 13811 13812 13813 13814 13815 13816 13817 13818 13819 13820 13821 13822 13823 13824 13825 13826 13827 13828 13829 13830 13831 13832 13833 13834 13835 13836 13837 13838 13839 13840 13841 13842 13843 13844 13845 13846 13847 13848 13849 13850 13851 13852 13853 13854 13855 13856 13857 13858 13859 13860 13861 13862 13863 13864 13865 13866 13867 13868 13869 13870 13871 13872 13873 13874 13875 13876 13877 13878 13879 13880 13881 13882 13883 13884 13885 13886 13887 13888 13889 13890 13891 13892 13893 13894 13895 13896 13897 13898 13899 13900 13901 13902 13903 13904 13905 13906 13907 13908 13909 13910 13911 13912 13913 13914 13915 13916 13917 13918 13919 13920 13921 13922 13923 13924 13925 13926 13927 13928 13929 13930 13931 13932 13933 13934 13935 13936 13937 13938 13939 13940 13941 13942 13943 13944 13945 13946 13947 13948 13949 13950 13951 13952 13953 13954 13955 13956 13957 13958 13959 13960 13961 13962 13963 13964 13965 13966 13967 13968 13969 13970 13971 13972 13973 13974 13975 13976 13977 13978 13979 13980 13981 13982 13983 13984 13985 13986 13987 13988 13989 13990 13991 13992 13993 13994 13995 13996 13997 13998 13999 14000 14001 14002 14003 14004 14005 14006 14007 14008 14009 14010 14011 14012 14013 14014 14015 14016 14017 14018 14019 14020 14021 14022 14023 14024 14025 14026 14027 14028 14029 14030 14031 14032 14033 14034 14035 14036 14037 14038 14039 14040 14041 14042 14043 14044 14045 14046 14047 14048 14049 14050 14051 14052 14053 14054 14055 14056 14057 14058 14059 14060 14061 14062 14063 14064 14065 14066 14067 14068 14069 14070 14071 14072 14073 14074 14075 14076 14077 14078 14079 14080 14081 14082 14083 14084 14085 14086 14087 14088 14089 14090 14091 14092 14093 14094 14095 14096 14097 14098 14099 14100 14101 14102 14103 14104 14105 14106 14107 14108 14109 14110 14111 14112 14113 14114 14115 14116 14117 14118 14119 14120 14121 14122 14123 14124 14125 14126 14127 14128 14129 14130 14131 14132 14133 14134 14135 14136 14137 14138 14139 14140 14141 14142 14143 14144 14145 14146 14147 14148 14149 14150 14151 14152 14153 14154 14155 14156 14157 14158 14159 14160 14161 14162 14163 14164 14165 14166 14167 14168 14169 14170 14171 14172 14173 14174 14175 14176 14177 14178 14179 14180 14181 14182 14183 14184 14185 14186 14187 14188 14189 14190 14191 14192 14193 14194 14195 14196 14197 14198 14199 14200 14201 14202 14203 14204 14205 14206 14207 14208 14209 14210 14211 14212 14213 14214 14215 14216 14217 14218 14219 14220 14221 14222 14223 14224 14225 14226 14227 14228 14229 14230 14231 14232 14233 14234 14235 14236 14237 14238 14239 14240 14241 14242 14243 14244 14245 14246 14247 14248 14249 14250 14251 14252 14253 14254 14255 14256 14257 14258 14259 14260 14261 14262 14263 14264 14265 14266 14267 14268 14269 14270 14271 14272 14273 14274 14275 14276 14277 14278 14279 14280 14281 14282 14283 14284 14285 14286 14287 14288 14289 14290 14291 14292 14293 14294 14295 14296 14297 14298 14299 14300 14301 14302 14303 14304 14305 14306 14307 14308 14309 14310 14311 14312 14313 14314 14315 14316 14317 14318 14319 14320 14321 14322 14323 14324 14325 14326 14327 14328 14329 14330 14331 14332 14333 14334 14335 14336 14337 14338 14339 14340 14341 14342 14343 14344 14345 14346 14347 14348 14349 14350 14351 14352 14353 14354 14355 14356 14357 14358 14359 14360 14361 14362 14363 14364 14365 14366 14367 14368 14369 14370 14371 14372 14373 14374 14375 14376 14377 14378 14379 14380 14381 14382 14383 14384 14385 14386 14387 14388 14389 14390 14391 14392 14393 14394 14395 14396 14397 14398 14399 14400 14401 14402 14403 14404 14405 14406 14407 14408 14409 14410 14411 14412 14413 14414 14415 14416 14417 14418 14419 14420 14421 14422 14423 14424 14425 14426 14427 14428 14429 14430 14431 14432 14433 14434 14435 14436 14437 14438 14439 14440 14441 14442 14443 14444 14445 14446 14447 14448 14449 14450 14451 14452 14453 14454 14455 14456 14457 14458 14459 14460 14461 14462 14463 14464 14465 14466 14467 14468 14469 14470 14471 14472 14473 14474 14475 14476 14477 14478 14479 14480 14481 14482 14483 14484 14485 14486 14487 14488 14489 14490 14491 14492 14493 14494 14495 14496 14497 14498 14499 14500 14501 14502 14503 14504 14505 14506 14507 14508 14509 14510 14511 14512 14513 14514 14515 14516 14517 14518 14519 14520 14521 14522 14523 14524 14525 14526 14527 14528 14529 14530 14531 14532 14533 14534 14535 14536 14537 14538 14539 14540 14541 14542 14543 14544 14545 14546 14547 14548 14549 14550 14551 14552 14553 14554 14555 14556 14557 14558 14559 14560 14561 14562 14563 14564 14565 14566 14567 14568 14569 14570 14571 14572 14573 14574 14575 14576 14577 14578 14579 14580 14581 14582 14583 14584 14585 14586 14587 14588 14589 14590 14591 14592 14593 14594 14595 14596 14597 14598 14599 14600 14601 14602 14603 14604 14605 14606 14607 14608 14609 14610 14611 14612 14613 14614 14615 14616 14617 14618 14619 14620 14621 14622 14623 14624 14625 14626 14627 14628 14629 14630 14631 14632 14633 14634 14635 14636 14637 14638 14639 14640 14641 14642 14643 14644 14645 14646 14647 14648 14649 14650 14651 14652 14653 14654 14655 14656 14657 14658 14659 14660 14661 14662 14663 14664 14665 14666 14667 14668 14669 14670 14671 14672 14673 14674 14675 14676 14677 14678 14679 14680 14681 14682 14683 14684 14685 14686 14687 14688 14689 14690 14691 14692 14693 14694 14695 14696 14697 14698 14699 14700 14701 14702 14703 14704 14705 14706 14707 14708 14709 14710 14711 14712 14713 14714 14715 14716 14717 14718 14719 14720 14721 14722 14723 14724 14725 14726 14727 14728 14729 14730 14731 14732 14733 14734 14735 14736 14737 14738 14739 14740 14741 14742 14743 14744 14745 14746 14747 14748 14749 14750 14751 14752 14753 14754 14755 14756 14757 14758 14759 14760 14761 14762 14763 14764 14765 14766 14767 14768 14769 14770 14771 14772 14773 14774 14775 14776 14777 14778 14779 14780 14781 14782 14783 14784 14785 14786 14787 14788 14789 14790 14791 14792 14793 14794 14795 14796 14797 14798 14799 14800 14801 14802 14803 14804 14805 14806 14807 14808 14809 14810 14811 14812 14813 14814 14815 14816 14817 14818 14819 14820 14821 14822 14823 14824 14825 14826 14827 14828 14829 14830 14831 14832 14833 14834 14835 14836 14837 14838 14839 14840 14841 14842 14843 14844 14845 14846 14847 14848 14849 14850 14851 14852 14853 14854 14855 14856 14857 14858 14859 14860 14861 14862 14863 14864 14865 14866 14867 14868 14869 14870 14871 14872 14873 14874 14875 14876 14877 14878 14879 14880 14881 14882 14883 14884 14885 14886 14887 14888 14889 14890 14891 14892 14893 14894 14895 14896 14897 14898 14899 14900 14901 14902 14903 14904 14905 14906 14907 14908 14909 14910 14911 14912 14913 14914 14915 14916 14917 14918 14919 14920 14921 14922 14923 14924 14925 14926 14927 14928 14929 14930 14931 14932 14933 14934 14935 14936 14937 14938 14939 14940 14941 14942 14943 14944 14945 14946 14947 14948 14949 14950 14951 14952 14953 14954 14955 14956 14957 14958 14959 14960 14961 14962 14963 14964 14965 14966 14967 14968 14969 14970 14971 14972 14973 14974 14975 14976 14977 14978 14979 14980 14981 14982 14983 14984 14985 14986 14987 14988 14989 14990 14991 14992 14993 14994 14995 14996 14997 14998 14999 15000 15001 15002 15003 15004 15005 15006 15007 15008 15009 15010 15011 15012 15013 15014 15015 15016 15017 15018 15019 15020 15021 15022 15023 15024 15025 15026 15027 15028 15029 15030 15031 15032 15033 15034 15035 15036 15037 15038 15039 15040 15041 15042 15043 15044 15045 15046 15047 15048 15049 15050 15051 15052 15053 15054 15055 15056 15057 15058 15059 15060 15061 15062 15063 15064 15065 15066 15067 15068 15069 15070 15071 15072 15073 15074 15075 15076 15077 15078 15079 15080 15081 15082 15083 15084 15085 15086 15087 15088 15089 15090 15091 15092 15093 15094 15095 15096 15097 15098 15099 15100 15101 15102 15103 15104 15105 15106 15107 15108 15109 15110 15111 15112 15113 15114 15115 15116 15117 15118 15119 15120 15121 15122 15123 15124 15125 15126 15127 15128 15129 15130 15131 15132 15133 15134 15135 15136 15137 15138 15139 15140 15141 15142 15143 15144 15145 15146 15147 15148 15149 15150 15151 15152 15153 15154 15155 15156 15157 15158 15159 15160 15161 15162 15163 15164 15165 15166 15167 15168 15169 15170 15171 15172 15173 15174 15175 15176 15177 15178 15179 15180 15181 15182 15183 15184 15185 15186 15187 15188 15189 15190 15191 15192 15193 15194 15195 15196 15197 15198 15199 15200 15201 15202 15203 15204 15205 15206 15207 15208 15209 15210 15211 15212 15213 15214 15215 15216 15217 15218 15219 15220 15221 15222 15223 15224 15225 15226 15227 15228 15229 15230 15231 15232 15233 15234 15235 15236 15237 15238 15239 15240 15241 15242 15243 15244 15245 15246 15247 15248 15249 15250 15251 15252 15253 15254 15255 15256 15257 15258 15259 15260 15261 15262 15263 15264 15265 15266 15267 15268 15269 15270 15271 15272 15273 15274 15275 15276 15277 15278 15279 15280 15281 15282 15283 15284 15285 15286 15287 15288 15289 15290 15291 15292 15293 15294 15295 15296 15297 15298 15299 15300 15301 15302 15303 15304 15305 15306 15307 15308 15309 15310 15311 15312 15313 15314 15315 15316 15317 15318 15319 15320 15321 15322 15323 15324 15325 15326 15327 15328 15329 15330 15331 15332 15333 15334 15335 15336 15337 15338 15339 15340 15341 15342 15343 15344 15345 15346 15347 15348 15349 15350 15351 15352 15353 15354 15355 15356 15357 15358 15359 15360 15361 15362 15363 15364 15365 15366 15367 15368 15369 15370 15371 15372 15373 15374 15375 15376 15377 15378 15379 15380 15381 15382 15383 15384 15385 15386 15387 15388 15389 15390 15391 15392 15393 15394 15395 15396 15397 15398 15399 15400 15401 15402 15403 15404 15405 15406 15407 15408 15409 15410 15411 15412 15413 15414 15415 15416 15417 15418 15419 15420 15421 15422 15423 15424 15425 15426 15427 15428 15429 15430 15431 15432 15433 15434 15435 15436 15437 15438 15439 15440 15441 15442 15443 15444 15445 15446 15447 15448 15449 15450 15451 15452 15453 15454 15455 15456 15457 15458 15459 15460 15461 15462 15463 15464 15465 15466 15467 15468 15469 15470 15471 15472 15473 15474 15475 15476 15477 15478 15479 15480 15481 15482 15483 15484 15485 15486 15487 15488 15489 15490 15491 15492 15493 15494 15495 15496 15497 15498 15499 15500 15501 15502 15503 15504 15505 15506 15507 15508 15509 15510 15511 15512 15513 15514 15515 15516 15517 15518 15519 15520 15521 15522 15523 15524 15525 15526 15527 15528 15529 15530 15531 15532 15533 15534 15535 15536 15537 15538 15539 15540 15541 15542 15543 15544 15545 15546 15547 15548 15549 15550 15551 15552 15553 15554 15555 15556 15557 15558 15559 15560 15561 15562 15563 15564 15565 15566 15567 15568 15569 15570 15571 15572 15573 15574 15575 15576 15577 15578 15579 15580 15581 15582 15583 15584 15585 15586 15587 15588 15589 15590 15591 15592 15593 15594 15595 15596 15597 15598 15599 15600 15601 15602 15603 15604 15605 15606 15607 15608 15609 15610 15611 15612 15613 15614 15615 15616 15617 15618 15619 15620 15621 15622 15623 15624 15625 15626 15627 15628 15629 15630 15631 15632 15633 15634 15635 15636 15637 15638 15639 15640 15641 15642 15643 15644 15645 15646 15647 15648 15649 15650 15651 15652 15653 15654 15655 15656 15657 15658 15659 15660 15661 15662 15663 15664 15665 15666 15667 15668 15669 15670 15671 15672 15673 15674 15675 15676 15677 15678 15679 15680 15681 15682 15683 15684 15685 15686 15687 15688 15689 15690 15691 15692 15693 15694 15695 15696 15697 15698 15699 15700 15701 15702 15703 15704 15705 15706 15707 15708 15709 15710 15711 15712 15713 15714 15715 15716 15717 15718 15719 15720 15721 15722 15723 15724 15725 15726 15727 15728 15729 15730 15731 15732 15733 15734 15735 15736 15737 15738 15739 15740 15741 15742 15743 15744 15745 15746 15747 15748 15749 15750 15751 15752 15753 15754 15755 15756 15757 15758 15759 15760 15761 15762 15763 15764 15765 15766 15767 15768 15769 15770 15771 15772 15773 15774 15775 15776 15777 15778 15779 15780 15781 15782 15783 15784 15785 15786 15787 15788 15789 15790 15791 15792 15793 15794 15795 15796 15797 15798 15799 15800 15801 15802 15803 15804 15805 15806 15807 15808 15809 15810 15811 15812 15813 15814 15815 15816 15817 15818 15819 15820 15821 15822 15823 15824 15825 15826 15827 15828 15829 15830 15831 15832 15833 15834 15835 15836 15837 15838 15839 15840 15841 15842 15843 15844 15845 15846 15847 15848 15849 15850 15851 15852 15853 15854 15855 15856 15857 15858 15859 15860 15861 15862 15863 15864 15865 15866 15867 15868 15869 15870 15871 15872 15873 15874 15875 15876 15877 15878 15879 15880 15881 15882 15883 15884 15885 15886 15887 15888 15889 15890 15891 15892 15893 15894 15895 15896 15897 15898 15899 15900 15901 15902 15903 15904 15905 15906 15907 15908 15909 15910 15911 15912 15913 15914 15915 15916 15917 15918 15919 15920 15921 15922 15923 15924 15925 15926 15927 15928 15929 15930 15931 15932 15933 15934 15935 15936 15937 15938 15939 15940 15941 15942 15943 15944 15945 15946 15947 15948 15949 15950 15951 15952 15953 15954 15955 15956 15957 15958 15959 15960 15961 15962 15963 15964 15965 15966 15967 15968 15969 15970 15971 15972 15973 15974 15975 15976 15977 15978 15979 15980 15981 15982 15983 15984 15985 15986 15987 15988 15989 15990 15991 15992 15993 15994 15995 15996 15997 15998 15999 16000 16001 16002 16003 16004 16005 16006 16007 16008 16009 16010 16011 16012 16013 16014 16015 16016 16017 16018 16019 16020 16021 16022 16023 16024 16025 16026 16027 16028 16029 16030 16031 16032 16033 16034 16035 16036 16037 16038 16039 16040 16041 16042 16043 16044 16045 16046 16047 16048 16049 16050 16051 16052 16053 16054 16055 16056 16057 16058 16059 16060 16061 16062 16063 16064 16065 16066 16067 16068 16069 16070 16071 16072 16073 16074 16075 16076 16077 16078 16079 16080 16081 16082 16083 16084 16085 16086 16087 16088 16089 16090 16091 16092 16093 16094 16095 16096 16097 16098 16099 16100 16101 16102 16103 16104 16105 16106 16107 16108 16109 16110 16111 16112 16113 16114 16115 16116 16117 16118 16119 16120 16121 16122 16123 16124 16125 16126 16127 16128 16129 16130 16131 16132 16133 16134 16135 16136 16137 16138 16139 16140 16141 16142 16143 16144 16145 16146 16147 16148 16149 16150 16151 16152 16153 16154 16155 16156 16157 16158 16159 16160 16161 16162 16163 16164 16165 16166 16167 16168 16169 16170 16171 16172 16173 16174 16175 16176 16177 16178 16179 16180 16181 16182 16183 16184 16185 16186 16187 16188 16189 16190 16191 16192 16193 16194 16195 16196 16197 16198 16199 16200 16201 16202 16203 16204 16205 16206 16207 16208 16209 16210 16211 16212 16213 16214 16215 16216 16217 16218 16219 16220 16221 16222 16223 16224 16225 16226 16227 16228 16229 16230 16231 16232 16233 16234 16235 16236 16237 16238 16239 16240 16241 16242 16243 16244 16245 16246 16247 16248 16249 16250 16251 16252 16253 16254 16255 16256 16257 16258 16259 16260 16261 16262 16263 16264 16265 16266 16267 16268 16269 16270 16271 16272 16273 16274 16275 16276 16277 16278 16279 16280 16281 16282 16283 16284 16285 16286 16287 16288 16289 16290 16291 16292 16293 16294 16295 16296 16297 16298 16299 16300 16301 16302 16303 16304 16305 16306 16307 16308 16309 16310 16311 16312 16313 16314 16315 16316 16317 16318 16319 16320 16321 16322 16323 16324 16325 16326 16327 16328 16329 16330 16331 16332 16333 16334 16335 16336 16337 16338 16339 16340 16341 16342 16343 16344 16345 16346 16347 16348 16349 16350 16351 16352 16353 16354 16355 16356 16357 16358 16359 16360 16361 16362 16363 16364 16365 16366 16367 16368 16369 16370 16371 16372 16373 16374 16375 16376 16377 16378 16379 16380 16381 16382 16383 16384 16385 16386 16387 16388 16389 16390 16391 16392 16393 16394 16395 16396 16397 16398 16399 16400 16401 16402 16403 16404 16405 16406 16407 16408 16409 16410 16411 16412 16413 16414 16415 16416 16417 16418 16419 16420 16421 16422 16423 16424 16425 16426 16427 16428 16429 16430 16431 16432 16433 16434 16435 16436 16437 16438 16439 16440 16441 16442 16443 16444 16445 16446 16447 16448 16449 16450 16451 16452 16453 16454 16455 16456 16457 16458 16459 16460 16461 16462 16463 16464 16465 16466 16467 16468 16469 16470 16471 16472 16473 16474 16475 16476 16477 16478 16479 16480 16481 16482 16483 16484 16485 16486 16487 16488 16489 16490 16491 16492 16493 16494 16495 16496 16497 16498 16499 16500 16501 16502 16503 16504 16505 16506 16507 16508 16509 16510 16511 16512 16513 16514 16515 16516 16517 16518 16519 16520 16521 16522 16523 16524 16525 16526 16527 16528 16529 16530 16531 16532 16533 16534 16535 16536 16537 16538 16539 16540 16541 16542 16543 16544 16545 16546 16547 16548 16549 16550 16551 16552 16553 16554 16555 16556 16557 16558 16559 16560 16561 16562 16563 16564 16565 16566 16567 16568 16569 16570 16571 16572 16573 16574 16575 16576 16577 16578 16579 16580 16581 16582 16583 16584 16585 16586 16587 16588 16589 16590 16591 16592 16593 16594 16595 16596 16597 16598 16599 16600 16601 16602 16603 16604 16605 16606 16607 16608 16609 16610 16611 16612 16613 16614 16615 16616 16617 16618 16619 16620 16621 16622 16623 16624 16625 16626 16627 16628 16629 16630 16631 16632 16633 16634 16635 16636 16637 16638 16639 16640 16641 16642 16643 16644 16645 16646 16647 16648 16649 16650 16651 16652 16653 16654 16655 16656 16657 16658 16659 16660 16661 16662 16663 16664 16665 16666 16667 16668 16669 16670 16671 16672 16673 16674 16675 16676 16677 16678 16679 16680 16681 16682 16683 16684 16685 16686 16687 16688 16689 16690 16691 16692 16693 16694 16695 16696 16697 16698 16699 16700 16701 16702 16703 16704 16705 16706 16707 16708 16709 16710 16711 16712 16713 16714 16715 16716 16717 16718 16719 16720 16721 16722 16723 16724 16725 16726 16727 16728 16729 16730 16731 16732 16733 16734 16735 16736 16737 16738 16739 16740 16741 16742 16743 16744 16745 16746 16747 16748 16749 16750 16751 16752 16753 16754 16755 16756 16757 16758 16759 16760 16761 16762 16763 16764 16765 16766 16767 16768 16769 16770 16771 16772 16773 16774 16775 16776 16777 16778 16779 16780 16781 16782 16783 16784 16785 16786 16787 16788 16789 16790 16791 16792 16793 16794 16795 16796 16797 16798 16799 16800 16801 16802 16803 16804 16805 16806 16807 16808 16809 16810 16811 16812 16813 16814 16815 16816 16817 16818 16819 16820 16821 16822 16823 16824 16825 16826 16827 16828 16829 16830 16831 16832 16833 16834 16835 16836 16837 16838 16839 16840 16841 16842 16843 16844 16845 16846 16847 16848 16849 16850 16851 16852 16853 16854 16855 16856 16857 16858 16859 16860 16861 16862 16863 16864 16865 16866 16867 16868 16869 16870 16871 16872 16873 16874 16875 16876 16877 16878 16879 16880 16881 16882 16883 16884 16885 16886 16887 16888 16889 16890 16891 16892 16893 16894 16895 16896 16897 16898 16899 16900 16901 16902 16903 16904 16905 16906 16907 16908 16909 16910 16911 16912 16913 16914 16915 16916 16917 16918 16919 16920 16921 16922 16923 16924 16925 16926 16927 16928 16929 16930 16931 16932 16933 16934 16935 16936 16937 16938 16939 16940 16941 16942 16943 16944 16945 16946 16947 16948 16949 16950 16951 16952 16953 16954 16955 16956 16957 16958 16959 16960 16961 16962 16963 16964 16965 16966 16967 16968 16969 16970 16971 16972 16973 16974 16975 16976 16977 16978 16979 16980 16981 16982 16983 16984 16985 16986 16987 16988 16989 16990 16991 16992 16993 16994 16995 16996 16997 16998 16999 17000 17001 17002 17003 17004 17005 17006 17007 17008 17009 17010 17011 17012 17013 17014 17015 17016 17017 17018 17019 17020 17021 17022 17023 17024 17025 17026 17027 17028 17029 17030 17031 17032 17033 17034 17035 17036 17037 17038 17039 17040 17041 17042 17043 17044 17045 17046 17047 17048 17049 17050 17051 17052 17053 17054 17055 17056 17057 17058 17059 17060 17061 17062 17063 17064 17065 17066 17067 17068 17069 17070 17071 17072 17073 17074 17075 17076 17077 17078 17079 17080 17081 17082 17083 17084 17085 17086 17087 17088 17089 17090 17091 17092 17093 17094 17095 17096 17097 17098 17099 17100 17101 17102 17103 17104 17105 17106 17107 17108 17109 17110 17111 17112 17113 17114 17115 17116 17117 17118 17119 17120 17121 17122 17123 17124 17125 17126 17127 17128 17129 17130 17131 17132 17133 17134 17135 17136 17137 17138 17139 17140 17141 17142 17143 17144 17145 17146 17147 17148 17149 17150 17151 17152 17153 17154 17155 17156 17157 17158 17159 17160 17161 17162 17163 17164 17165 17166 17167 17168 17169 17170 17171 17172 17173 17174 17175 17176 17177 17178 17179 17180 17181 17182 17183 17184 17185 17186 17187 17188 17189 17190 17191 17192 17193 17194 17195 17196 17197 17198 17199 17200 17201 17202 17203 17204 17205 17206 17207 17208 17209 17210 17211 17212 17213 17214 17215 17216 17217 17218 17219 17220 17221 17222 17223 17224 17225 17226 17227 17228 17229 17230 17231 17232 17233 17234 17235 17236 17237 17238 17239 17240 17241 17242 17243 17244 17245 17246 17247 17248 17249 17250 17251 17252 17253 17254 17255 17256 17257 17258 17259 17260 17261 17262 17263 17264 17265 17266 17267 17268 17269 17270 17271 17272 17273 17274 17275 17276 17277 17278 17279 17280 17281 17282 17283 17284 17285 17286 17287 17288 17289 17290 17291 17292 17293 17294 17295 17296 17297 17298 17299 17300 17301 17302 17303 17304 17305 17306 17307 17308 17309 17310 17311 17312 17313 17314 17315 17316 17317 17318 17319 17320 17321 17322 17323 17324 17325 17326 17327 17328 17329 17330 17331 17332 17333 17334 17335 17336 17337 17338 17339 17340 17341 17342 17343 17344 17345 17346 17347 17348 17349 17350 17351 17352 17353 17354 17355 17356 17357 17358 17359 17360 17361 17362 17363 17364 17365 17366 17367 17368 17369 17370 17371 17372 17373 17374 17375 17376 17377 17378 17379 17380 17381 17382 17383 17384 17385 17386 17387 17388 17389 17390 17391 17392 17393 17394 17395 17396 17397 17398 17399 17400 17401 17402 17403 17404 17405 17406 17407 17408 17409 17410 17411 17412 17413 17414 17415 17416 17417 17418 17419 17420 17421 17422 17423 17424 17425 17426 17427 17428 17429 17430 17431 17432 17433 17434 17435 17436 17437 17438 17439 17440 17441 17442 17443 17444 17445 17446 17447 17448 17449 17450 17451 17452 17453 17454 17455 17456 17457 17458 17459 17460 17461 17462 17463 17464 17465 17466 17467 17468 17469 17470 17471 17472 17473 17474 17475 17476 17477 17478 17479 17480 17481 17482 17483 17484 17485 17486 17487 17488 17489 17490 17491 17492 17493 17494 17495 17496 17497 17498 17499 17500 17501 17502 17503 17504 17505 17506 17507 17508 17509 17510 17511 17512 17513 17514 17515 17516 17517 17518 17519 17520 17521 17522 17523 17524 17525 17526 17527 17528 17529 17530 17531 17532 17533 17534 17535 17536 17537 17538 17539 17540 17541 17542 17543 17544 17545 17546 17547 17548 17549 17550 17551 17552 17553 17554 17555 17556 17557 17558 17559 17560 17561 17562 17563 17564 17565 17566 17567 17568 17569 17570 17571 17572 17573 17574 17575 17576 17577 17578 17579 17580 17581 17582 17583 17584 17585 17586 17587 17588 17589 17590 17591 17592 17593 17594 17595 17596 17597 17598 17599 17600 17601 17602 17603 17604 17605 17606 17607 17608 17609 17610 17611 17612 17613 17614 17615 17616 17617 17618 17619 17620 17621 17622 17623 17624 17625 17626 17627 17628 17629 17630 17631 17632 17633 17634 17635 17636 17637 17638 17639 17640 17641 17642 17643 17644 17645 17646 17647 17648 17649 17650 17651 17652 17653 17654 17655 17656 17657 17658 17659 17660 17661 17662 17663 17664 17665 17666 17667 17668 17669 17670 17671 17672 17673 17674 17675 17676 17677 17678 17679 17680 17681 17682 17683 17684 17685 17686 17687 17688 17689 17690 17691 17692 17693 17694 17695 17696 17697 17698 17699 17700 17701 17702 17703 17704 17705 17706 17707 17708 17709 17710 17711 17712 17713 17714 17715 17716 17717 17718 17719 17720 17721 17722 17723 17724 17725 17726 17727 17728 17729 17730 17731 17732 17733 17734 17735 17736 17737 17738 17739 17740 17741 17742 17743 17744 17745 17746 17747 17748 17749 17750 17751 17752 17753 17754 17755 17756 17757 17758 17759 17760 17761 17762 17763 17764 17765 17766 17767 17768 17769 17770 17771 17772 17773 17774 17775 17776 17777 17778 17779 17780 17781 17782 17783 17784 17785 17786 17787 17788 17789 17790 17791 17792 17793 17794 17795 17796 17797 17798 17799 17800 17801 17802 17803 17804 17805 17806 17807 17808 17809 17810 17811 17812 17813 17814 17815 17816 17817 17818 17819 17820 17821 17822 17823 17824 17825 17826 17827 17828 17829 17830 17831 17832 17833 17834 17835 17836 17837 17838 17839 17840 17841 17842 17843 17844 17845 17846 17847 17848 17849 17850 17851 17852 17853 17854 17855 17856 17857 17858 17859 17860 17861 17862 17863 17864 17865 17866 17867 17868 17869 17870 17871 17872 17873 17874 17875 17876 17877 17878 17879 17880 17881 17882 17883 17884 17885 17886 17887 17888 17889 17890 17891 17892 17893 17894 17895 17896 17897 17898 17899 17900 17901 17902 17903 17904 17905 17906 17907 17908 17909 17910 17911 17912 17913 17914 17915 17916 17917 17918 17919 17920 17921 17922 17923 17924 17925 17926 17927 17928 17929 17930 17931 17932 17933 17934 17935 17936 17937 17938 17939 17940 17941 17942 17943 17944 17945 17946 17947 17948 17949 17950 17951 17952 17953 17954 17955 17956 17957 17958 17959 17960 17961 17962 17963 17964 17965 17966 17967 17968 17969 17970 17971 17972 17973 17974 17975 17976 17977 17978 17979 17980 17981 17982 17983 17984 17985 17986 17987 17988 17989 17990 17991 17992 17993 17994 17995 17996 17997 17998 17999 18000 18001 18002 18003 18004 18005 18006 18007 18008 18009 18010 18011 18012 18013 18014 18015 18016 18017 18018 18019 18020 18021 18022 18023 18024 18025 18026 18027 18028 18029 18030 18031 18032 18033 18034 18035 18036 18037 18038 18039 18040 18041 18042 18043 18044 18045 18046 18047 18048 18049 18050 18051 18052 18053 18054 18055 18056 18057 18058 18059 18060 18061 18062 18063 18064 18065 18066 18067 18068 18069 18070 18071 18072 18073 18074 18075 18076 18077 18078 18079 18080 18081 18082 18083 18084 18085 18086 18087 18088 18089 18090 18091 18092 18093 18094 18095 18096 18097 18098 18099 18100 18101 18102 18103 18104 18105 18106 18107 18108 18109 18110 18111 18112 18113 18114 18115 18116 18117 18118 18119 18120 18121 18122 18123 18124 18125 18126 18127 18128 18129 18130 18131 18132 18133 18134 18135 18136 18137 18138 18139 18140 18141 18142 18143 18144 18145 18146 18147 18148 18149 18150 18151 18152 18153 18154 18155 18156 18157 18158 18159 18160 18161 18162 18163 18164 18165 18166 18167 18168 18169 18170 18171 18172 18173 18174 18175 18176 18177 18178 18179 18180 18181 18182 18183 18184 18185 18186 18187 18188 18189 18190 18191 18192 18193 18194 18195 18196 18197 18198 18199 18200 18201 18202 18203 18204 18205 18206 18207 18208 18209 18210 18211 18212 18213 18214 18215 18216 18217 18218 18219 18220 18221 18222 18223 18224 18225 18226 18227 18228 18229 18230 18231 18232 18233 18234 18235 18236 18237 18238 18239 18240 18241 18242 18243 18244 18245 18246 18247 18248 18249 18250 18251 18252 18253 18254 18255 18256 18257 18258 18259 18260 18261 18262 18263 18264 18265 18266 18267 18268 18269 18270 18271 18272 18273 18274 18275 18276 18277 18278 18279 18280 18281 18282 18283 18284 18285 18286 18287 18288 18289 18290 18291 18292 18293 18294 18295 18296 18297 18298 18299 18300 18301 18302 18303 18304 18305 18306 18307 18308 18309 18310 18311 18312 18313 18314 18315 18316 18317 18318 18319 18320 18321 18322 18323 18324 18325 18326 18327 18328 18329 18330 18331 18332 18333 18334 18335 18336 18337 18338 18339 18340 18341 18342 18343 18344 18345 18346 18347 18348 18349 18350 18351 18352 18353 18354 18355 18356 18357 18358 18359 18360 18361 18362 18363 18364 18365 18366 18367 18368 18369 18370 18371 18372 18373 18374 18375 18376 18377 18378 18379 18380 18381 18382 18383 18384 18385 18386 18387 18388 18389 18390 18391 18392 18393 18394 18395 18396 18397 18398 18399 18400 18401 18402 18403 18404 18405 18406 18407 18408 18409 18410 18411 18412 18413 18414 18415 18416 18417 18418 18419 18420 18421 18422 18423 18424 18425 18426 18427 18428 18429 18430 18431 18432 18433 18434 18435 18436 18437 18438 18439 18440 18441 18442 18443 18444 18445 18446 18447 18448 18449 18450 18451 18452 18453 18454 18455 18456 18457 18458 18459 18460 18461 18462 18463 18464 18465 18466 18467 18468 18469 18470 18471 18472 18473 18474 18475 18476 18477 18478 18479 18480 18481 18482 18483 18484 18485 18486 18487 18488 18489 18490 18491 18492 18493 18494 18495 18496 18497 18498 18499 18500 18501 18502 18503 18504 18505 18506 18507 18508 18509 18510 18511 18512 18513 18514 18515 18516 18517 18518 18519 18520 18521 18522 18523 18524 18525 18526 18527 18528 18529 18530 18531 18532 18533 18534 18535 18536 18537 18538 18539 18540 18541 18542 18543 18544 18545 18546 18547 18548 18549 18550 18551 18552 18553 18554 18555 18556 18557 18558 18559 18560 18561 18562 18563 18564 18565 18566 18567 18568 18569 18570 18571 18572 18573 18574 18575 18576 18577 18578 18579 18580 18581 18582 18583 18584 18585 18586 18587 18588 18589 18590 18591 18592 18593 18594 18595 18596 18597 18598 18599 18600 18601 18602 18603 18604 18605 18606 18607 18608 18609 18610 18611 18612 18613 18614 18615 18616 18617 18618 18619 18620 18621 18622 18623 18624 18625 18626 18627 18628 18629 18630 18631 18632 18633 18634 18635 18636 18637 18638 18639 18640 18641 18642 18643 18644 18645 18646 18647 18648 18649 18650 18651 18652 18653 18654 18655 18656 18657 18658 18659 18660 18661 18662 18663 18664 18665 18666 18667 18668 18669 18670 18671 18672 18673 18674 18675 18676 18677 18678 18679 18680 18681 18682 18683 18684 18685 18686 18687 18688 18689 18690 18691 18692 18693 18694 18695 18696 18697 18698 18699 18700 18701 18702 18703 18704 18705 18706 18707 18708 18709 18710 18711 18712 18713 18714 18715 18716 18717 18718 18719 18720 18721 18722 18723 18724 18725 18726 18727 18728 18729 18730 18731 18732 18733 18734 18735 18736 18737 18738 18739 18740 18741 18742 18743 18744 18745 18746 18747 18748 18749 18750 18751 18752 18753 18754 18755 18756 18757 18758 18759 18760 18761 18762 18763 18764 18765 18766 18767 18768 18769 18770 18771 18772 18773 18774 18775 18776 18777 18778 18779 18780 18781 18782 18783 18784 18785 18786 18787 18788 18789 18790 18791 18792 18793 18794 18795 18796 18797 18798 18799 18800 18801 18802 18803 18804 18805 18806 18807 18808 18809 18810 18811 18812 18813 18814 18815 18816 18817 18818 18819 18820 18821 18822 18823 18824 18825 18826 18827 18828 18829 18830 18831 18832 18833 18834 18835 18836 18837 18838 18839 18840 18841 18842 18843 18844 18845 18846 18847 18848 18849 18850 18851 18852 18853 18854 18855 18856 18857 18858 18859 18860 18861 18862 18863 18864 18865 18866 18867 18868 18869 18870 18871 18872 18873 18874 18875 18876 18877 18878 18879 18880 18881 18882 18883 18884 18885 18886 18887 18888 18889 18890 18891 18892 18893 18894 18895 18896 18897 18898 18899 18900 18901 18902 18903 18904 18905 18906 18907 18908 18909 18910 18911 18912 18913 18914 18915 18916 18917 18918 18919 18920 18921 18922 18923 18924 18925 18926 18927 18928 18929 18930 18931 18932 18933 18934 18935 18936 18937 18938 18939 18940 18941 18942 18943 18944 18945 18946 18947 18948 18949 18950 18951 18952 18953 18954 18955 18956 18957 18958 18959 18960 18961 18962 18963 18964 18965 18966 18967 18968 18969 18970 18971 18972 18973 18974 18975 18976 18977 18978 18979 18980 18981 18982 18983 18984 18985 18986 18987 18988 18989 18990 18991 18992 18993 18994 18995 18996 18997 18998 18999 19000 19001 19002 19003 19004 19005 19006 19007 19008 19009 19010 19011 19012 19013 19014 19015 19016 19017 19018 19019 19020 19021 19022 19023 19024 19025 19026 19027 19028 19029 19030 19031 19032 19033 19034 19035 19036 19037 19038 19039 19040 19041 19042 19043 19044 19045 19046 19047 19048 19049 19050 19051 19052 19053 19054 19055 19056 19057 19058 19059 19060 19061 19062 19063 19064 19065 19066 19067 19068 19069 19070 19071 19072 19073 19074 19075 19076 19077 19078 19079 19080 19081 19082 19083 19084 19085 19086 19087 19088 19089 19090 19091 19092 19093 19094 19095 19096 19097 19098 19099 19100 19101 19102 19103 19104 19105 19106 19107 19108 19109 19110 19111 19112 19113 19114 19115 19116 19117 19118 19119 19120 19121 19122 19123 19124 19125 19126 19127 19128 19129 19130 19131 19132 19133 19134 19135 19136 19137 19138 19139 19140 19141 19142 19143 19144 19145 19146 19147 19148 19149 19150 19151 19152 19153 19154 19155 19156 19157 19158 19159 19160 19161 19162 19163 19164 19165 19166 19167 19168 19169 19170 19171 19172 19173 19174 19175 19176 19177 19178 19179 19180 19181 19182 19183 19184 19185 19186 19187 19188 19189 19190 19191 19192 19193 19194 19195 19196 19197 19198 19199 19200 19201 19202 19203 19204 19205 19206 19207 19208 19209 19210 19211 19212 19213 19214 19215 19216 19217 19218 19219 19220 19221 19222 19223 19224 19225 19226 19227 19228 19229 19230 19231 19232 19233 19234 19235 19236 19237 19238 19239 19240 19241 19242 19243 19244 19245 19246 19247 19248 19249 19250 19251 19252 19253 19254 19255 19256 19257 19258 19259 19260 19261 19262 19263 19264 19265 19266 19267 19268 19269 19270 19271 19272 19273 19274 19275 19276 19277 19278 19279 19280 19281 19282 19283 19284 19285 19286 19287 19288 19289 19290 19291 19292 19293 19294 19295 19296 19297 19298 19299 19300 19301 19302 19303 19304 19305 19306 19307 19308 19309 19310 19311 19312 19313 19314 19315 19316 19317 19318 19319 19320 19321 19322 19323 19324 19325 19326 19327 19328 19329 19330 19331 19332 19333 19334 19335 19336 19337 19338 19339 19340 19341 19342 19343 19344 19345 19346 19347 19348 19349 19350 19351 19352 19353 19354 19355 19356 19357 19358 19359 19360 19361 19362 19363 19364 19365 19366 19367 19368 19369 19370 19371 19372 19373 19374 19375 19376 19377 19378 19379 19380 19381 19382 19383 19384 19385 19386 19387 19388 19389 19390 19391 19392 19393 19394 19395 19396 19397 19398 19399 19400 19401 19402 19403 19404 19405 19406 19407 19408 19409 19410 19411 19412 19413 19414 19415 19416 19417 19418 19419 19420 19421 19422 19423 19424 19425 19426 19427 19428 19429 19430 19431 19432 19433 19434 19435 19436 19437 19438 19439 19440 19441 19442 19443 19444 19445 19446 19447 19448 19449 19450 19451 19452 19453 19454 19455 19456 19457 19458 19459 19460 19461 19462 19463 19464 19465 19466 19467 19468 19469 19470 19471 19472 19473 19474 19475 19476 19477 19478 19479 19480 19481 19482 19483 19484 19485 19486 19487 19488 19489 19490 19491 19492 19493 19494 19495 19496 19497 19498 19499 19500 19501 19502 19503 19504 19505 19506 19507 19508 19509 19510 19511 19512 19513 19514 19515 19516 19517 19518 19519 19520 19521 19522 19523 19524 19525 19526 19527 19528 19529 19530 19531 19532 19533 19534 19535 19536 19537 19538 19539 19540 19541 19542 19543 19544 19545 19546 19547 19548 19549 19550 19551 19552 19553 19554 19555 19556 19557 19558 19559 19560 19561 19562 19563 19564 19565 19566 19567 19568 19569 19570 19571 19572 19573 19574 19575 19576 19577 19578 19579 19580 19581 19582 19583 19584 19585 19586 19587 19588 19589 19590 19591 19592 19593 19594 19595 19596 19597 19598 19599 19600 19601 19602 19603 19604 19605 19606 19607 19608 19609 19610 19611 19612 19613 19614 19615 19616 19617 19618 19619 19620 19621 19622 19623 19624 19625 19626 19627 19628 19629 19630 19631 19632 19633 19634 19635 19636 19637 19638 19639 19640 19641 19642 19643 19644 19645 19646 19647 19648 19649 19650 19651 19652 19653 19654 19655 19656 19657 19658 19659 19660 19661 19662 19663 19664 19665 19666 19667 19668 19669 19670 19671 19672 19673 19674 19675 19676 19677 19678 19679 19680 19681 19682 19683 19684 19685 19686 19687 19688 19689 19690 19691 19692 19693 19694 19695 19696 19697 19698 19699 19700 19701 19702 19703 19704 19705 19706 19707 19708 19709 19710 19711 19712 19713 19714 19715 19716 19717 19718 19719 19720 19721 19722 19723 19724 19725 19726 19727 19728 19729 19730 19731 19732 19733 19734 19735 19736 19737 19738 19739 19740 19741 19742 19743 19744 19745 19746 19747 19748 19749 19750 19751 19752 19753 19754 19755 19756 19757 19758 19759 19760 19761 19762 19763 19764 19765 19766 19767 19768 19769 19770 19771 19772 19773 19774 19775 19776 19777 19778 19779 19780 19781 19782 19783 19784 19785 19786 19787 19788 19789 19790 19791 19792 19793 19794 19795 19796 19797 19798 19799 19800 19801 19802 19803 19804 19805 19806 19807 19808 19809 19810 19811 19812 19813 19814 19815 19816 19817 19818 19819 19820 19821 19822 19823 19824 19825 19826 19827 19828 19829 19830 19831 19832 19833 19834 19835 19836 19837 19838 19839 19840 19841 19842 19843 19844 19845 19846 19847 19848 19849 19850 19851 19852 19853 19854 19855 19856 19857 19858 19859 19860 19861 19862 19863 19864 19865 19866 19867 19868 19869 19870 19871 19872 19873 19874 19875 19876 19877 19878 19879 19880 19881 19882 19883 19884 19885 19886 19887 19888 19889 19890 19891 19892 19893 19894 19895 19896 19897 19898 19899 19900 19901 19902 19903 19904 19905 19906 19907 19908 19909 19910 19911 19912 19913 19914 19915 19916 19917 19918 19919 19920 19921 19922 19923 19924 19925 19926 19927 19928 19929 19930 19931 19932 19933 19934 19935 19936 19937 19938 19939 19940 19941 19942 19943 19944 19945 19946 19947 19948 19949 19950 19951 19952 19953 19954 19955 19956 19957 19958 19959 19960 19961 19962 19963 19964 19965 19966 19967 19968 19969 19970 19971 19972 19973 19974 19975 19976 19977 19978 19979 19980 19981 19982 19983 19984 19985 19986 19987 19988 19989 19990 19991 19992 19993 19994 19995 19996 19997 19998 19999 20000 20001 20002 20003 20004 20005 20006 20007 20008 20009 20010 20011 20012 20013 20014 20015 20016 20017 20018 20019 20020 20021 20022 20023 20024 20025 20026 20027 20028 20029 20030 20031 20032 20033 20034 20035 20036 20037 20038 20039 20040 20041 20042 20043 20044 20045 20046
|
2 About_GT.M
About GT.M
GT.M runs on a wide variety of computer platforms. Consult FIS for the
current list of Supported platforms.
In addition to preserving the traditional features of M, GT.M also offers
an optimized compiler that produces object code that does not require
internal interpreters during execution.
On all platforms, the GT.M dynamic linking mechanism activates compiled
objects. On some platforms, you can link the object modules into shared
object libraries.
In keeping with the focus on creating fully compiled code, GT.M is tightly
integrated with the operating system environment and permits the use of
operating system utilities for program development.
GT.M also provides a full complement of M tools for creating, compiling,
and debugging source code. Many of these tasks are accomplished from the
GT.M facility called Direct Mode, which offers the look and feel of an
interpreted language that is familiar to the traditional M programmer.
2 Programming_Environment
Programming Environment
The GT.M Programming Environment is described in the following sections.
3 Managing_Data
Managing Data
The scope of M data is either process local or global.
* Local variables last only for the duration of the current session;
GT.M deletes them when the M process terminates.
* Global variables contain data that persists beyond the process. GT.M
stores global variables on disk. A Global Directory organizes global
variables and describes the organization of a database. The GT.M
administrator uses the Global Directory Editor (GDE) to create and
manage Global Directories. A Global Directory maps global names to a
database file. GT.M uses this mapping when it stores and retrieves
globals from the database. Several Global Directories may refer to a
single database file.
4 Database_Management
Database Management
The Global Directory Editor (GDE) creates, modifies, maintains, and
displays the characteristics of Global Directories. GDE also maps LOCKs on
resource names to the region of the database specified for the
corresponding global variables.
The M Peripheral Interchange Program (MUPIP) creates database files and
provides tools for GT.M database management and database journaling.
3 Managing_Source_Code
Managing Source Code
In the GT.M programming environment, source routines are generated and
stored as standard UNIX files. They are created and edited with standard
UNIX text editors.
GT.M is designed to work with the operating system utilities and enhances
them when beneficial. The following sections describe the process of
programming and debugging with GT.M and from the operating system.
4 Source_File_Management
Source File Management
In addition to standard M "percent" utilities, GT.M permits the use of the
standard UNIX file manipulation tools, for example, the diff, grep, cp,
and mv commands. The GT.M programmer can also use the powerful facilities
provided by the UNIX directory structure, such as time and date
information, tree-structured directories, and file protection codes.
GT.M programs are compatible with most source management software, for
example, RCS and SCCS.
4 Program_Debug
Program Debug
The GT.M programmer can use any UNIX text editor to create M source files.
If you generate a program from within the Direct Mode, it also accesses
the UNIX text editor specified by the environment variable EDITOR and
provides additional capabilities to automate and enhance the process.
The GT.M programmer also uses the Direct Mode facility to interactively
debug, modify, and execute M routines. In Direct Mode, GT.M executes each
M command immediately, as if it had been in-line at the point where GT.M
initiated Direct Mode.
The following is a list of additional enhancements available from the
Direct Mode:
5 GT.M_Compiler
GT.M Compiler
The GT.M compiler operates on source files to produce object files
consisting of position-independent, native object code, which on some
platforms can be linked into shared object libraries. GT.M provides syntax
error checking at compile-time and allows you to enable or disable the
compile-as-written mode. By default, GT.M produces an object file even if
the compiler detects errors in the source code. This compile-as-written
mode facilitates a flexible approach to debugging.
4 The_Run-Time_System
The Run-Time System
A GT.M programmer can execute an M routine from the shell or
interactively, using the M commands from Direct Mode.
The run-time system executes compile-as-written code as long as it does
not encounter the compile-time errors. If it detects an error, the
run-time system suspends execution of a routine immediately and transfers
control to Direct Mode or to a user-written error routine.
2 Copyright
Copyright
Copyright 1987 - 2003, 2013 - 2014
Fidelity Information Services, Inc. All rights reserved.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or any
later version published by the Free Software Foundation; with no Invariant
Sections, no Front-Cover Texts and no Back-Cover Texts.
GT.M(TM) is a trademark of Fidelity Information Services, Inc. Other
trademarks are the property of their respective owners.
This document contains a description of GT.M and the operating
instructions pertaining to the various functions that comprise the system.
This document does not contain any commitment of FIS. FIS believes the
information in this publication is accurate as of its publication date;
such information is subject to change without notice. FIS is not
responsible for any errors or defects.
1 Language_Extensions
Language Extensions
In addition to providing all of the ANSI standard M features, GT.M offers
a number of language extensions. In this chapter, the language extensions
are grouped by intended function to demonstrate their relationships to
each other and to the programming process. A summary table is provided in
each section.
The following sections describe the GT.M language extensions listed below:
* UNIX interface facilities
* Debugging tools
* Exception-handling extensions
* Journaling extensions
* Extensions providing additional capability
* Device Handling Extensions
* Alias Variables Extensions
* Extensions for Unicode Support
2 _Interface_Facilities
Interface Facilities
To improve efficiency and reduce duplication and inconsistency, GT.M is
closely integrated with the host operating system environment. With GT.M
you can gain access to the operating system facilities to examine:
* System information, such as quotas and SIDs
* Jobs and processes
* Directories and files
* Devices
* Messages
* Privileges
The following table summarizes the GT.M operating system interface
facilities.
+------------------------------------------------------------------------+
| Operating System Interface Facilities |
|------------------------------------------------------------------------|
| EXTENSION | EXPLANATION |
|-------------+----------------------------------------------------------|
| ZSYstem | Provides access to the shell. |
|-------------+----------------------------------------------------------|
| $ZMessage() | Translates an error condition code into text form. |
|-------------+----------------------------------------------------------|
| $ZCMdline | Contains a string value specifying the "excess" portion |
| | of the command line that invoked the GT.M process. |
|-------------+----------------------------------------------------------|
| $ZJob | Holds the pid of the process created by the last JOB |
| | command performed by the current process. |
|-------------+----------------------------------------------------------|
| $ZPARSE() | Parses a UNIX filename. |
|-------------+----------------------------------------------------------|
| $ZSEARCH() | Searches for one or more UNIX files. |
|-------------+----------------------------------------------------------|
| $ZSYstem | Contains the status code of the last ZSYSTEM. |
|-------------+----------------------------------------------------------|
| $ZTRNLNM() | Translates an environment variable. |
|-------------+----------------------------------------------------------|
| $ZDIRectory | Contains current working directory. |
+------------------------------------------------------------------------+
2 Debugging_Facilities
Debugging Facilities
GT.M provides a number of debugging features. These features include the
ability to:
* Interactively execute routines using M commands.
* Display lines that may contain errors using the ZPRINT command and the
$ZPOSITION special variable.
* Redisplay error messages using the $ZSTATUS special variable and the
ZMESSAGE command.
* Set breakpoints and actions to bypass an error using the ZBREAK
command.
* Execute a line at a time using the ZSTEP command.
* Display information about the M environment using the ZSHOW command.
* Modify the invocation stack with QUIT and ZGOTO.
* Incrementally add or modify code using the ZLINK and ZEDIT commands.
* Continue execution using the ZCONTINUE command.
* Establish "watch points" with triggers to trap incorrect accesses on
global variable updates.
The following table summarizes the GT.M language extensions that
facilitate debugging.
+------------------------------------------------------------------------+
| GT.M Debugging Tools |
|------------------------------------------------------------------------|
| EXTENSION | EXPLANATION |
|-------------+----------------------------------------------------------|
| ZBreak | Establishes a temporary breakpoint, with optional M |
| | action and/or activation count. |
|-------------+----------------------------------------------------------|
| ZContinue | Continues routine execution from a break. |
|-------------+----------------------------------------------------------|
| ZEDit | Invokes the UNIX text editor specified by the EDITOR |
| | environment variable. |
|-------------+----------------------------------------------------------|
| ZGoto | Removes multiple levels from the M invocation stack and |
| | transfers control. |
|-------------+----------------------------------------------------------|
| ZLink | Includes a new or modified M routine in the current M |
| | image; automatically recompiles if necessary. |
|-------------+----------------------------------------------------------|
| ZMessage | Signals the specified condition. |
|-------------+----------------------------------------------------------|
| ZPrint | Displays lines of source code. |
|-------------+----------------------------------------------------------|
| ZSHow | Displays information about the M environment. |
|-------------+----------------------------------------------------------|
| ZSTep | Incrementally executes a routine to the beginning of the |
| | next line of the same type. |
|-------------+----------------------------------------------------------|
| ZWRite | Displays all or some local or global variables. |
|-------------+----------------------------------------------------------|
| $ZCSTATUS | Holds the value of the status code for the last compile |
| | performed by a ZCOMPILE command. |
|-------------+----------------------------------------------------------|
| $ZEDit | Contains the status code for the last ZEDit. |
|-------------+----------------------------------------------------------|
| $ZJOBEXAM() | Performs a ZSHOW "*" to a default file location and |
| | name, or the one optionally specified by the argument. |
|-------------+----------------------------------------------------------|
| $ZLEVel | Contains the current level of DO/XECUTE nesting. |
|-------------+----------------------------------------------------------|
| $ZMessage() | Translates an error condition code into text form. |
|-------------+----------------------------------------------------------|
| $ZPOSition | Contains a string indicating the current execution |
| | location. |
|-------------+----------------------------------------------------------|
| $ZPROmpt | Controls the symbol displayed as the direct mode prompt. |
|-------------+----------------------------------------------------------|
| $ZROutines | Contains a string specifying a directory list containing |
| | the object, and optionally the source, files. |
|-------------+----------------------------------------------------------|
| | Contains name of the M source program most recently |
| $ZSOurce | ZLINKed or ZEDITed; default name for next ZEDIT or |
| | ZLINK. |
|-------------+----------------------------------------------------------|
| $ZStatus | Contains error condition code and location of the last |
| | exception condition occurring during routine execution. |
|-------------+----------------------------------------------------------|
| $ZSTep | Controls the default ZSTep action. |
+------------------------------------------------------------------------+
2 Exception_Handling_Facilities
Exception Handling Facilities
The GT.M exception trapping allows you to do the following:
* DO a recovery routine and resume the original command stream.
* GOTO any special handling; an extended ZGOTO provides for context
management.
* Report an error and enter Direct Mode for debugging.
* OPEN Input/Output devices with specific traps in addition to the main
trap.
* Trap and process an exception based on a device error.
* Trap and process an exception based on terminal input.
The following table summarizes the GT.M language extensions that
facilitate exception handling.
+------------------------------------------------------------------------+
| GT.M Exception Handling Extensions |
|------------------------------------------------------------------------|
| EXTENSION | EXPLANATION |
|-------------+----------------------------------------------------------|
| ZGoto | Removes zero or more levels from the M Invocation stack |
| | and, optionally, transfers control. |
|-------------+----------------------------------------------------------|
| ZMessage | Signals the specified condition. |
|-------------+----------------------------------------------------------|
| $ZCSTATUS | Holds the value of the status code for the last compile |
| | performed by a ZCOMPILE command. |
|-------------+----------------------------------------------------------|
| $ZEOF | Contains indication of whether the last READ reached |
| | end-of-file. |
|-------------+----------------------------------------------------------|
| $ZMessage() | Translates an error condition code into text form. |
|-------------+----------------------------------------------------------|
| $ZLevel | Contains current level of DO/XECUTE nesting. |
|-------------+----------------------------------------------------------|
| $ZStatus | Contains error condition code and location of last |
| | exception condition occurring during routine execution. |
|-------------+----------------------------------------------------------|
| $ZSYstem | Contains the status code of the last ZSYSTEM. |
|-------------+----------------------------------------------------------|
| $ZTrap | Contains an XECUTE string or entryref that GT.M invokes |
| | upon encountering an exception condition. |
|-------------+----------------------------------------------------------|
| | Provides a deviceparameter specifying an XECUTE string |
| EXCEPTION | or entryref that GT.M invokes upon encountering a |
| | device-related exception condition. |
+------------------------------------------------------------------------+
2 Journaling_Extensions
Journaling Extensions
Journaling records redundant copies of database update information to
increase protection against loss of information due to hardware and
software failure. GT.M provides the M commands ZTSTART and ZTCOMMIT, to
mark the beginning and end of a logical transaction. When ZTSTART and
ZTCOMMIT fence a logical transaction, which may consist of multiple global
variable updates, journal records can assure recovery of incomplete
application transactions.
The following table summarizes the GT.M language extensions for
journaling.
+------------------------------------------------------------------------+
| Journaling Extensions |
|------------------------------------------------------------------------|
| EXTENSION | EXPLANATION |
|-----------+------------------------------------------------------------|
| View | Extended to ensure that GT.M has transferred all updates |
| | to the journal file. |
|-----------+------------------------------------------------------------|
| ZTCommit | Marks the completion of a logical transaction. |
|-----------+------------------------------------------------------------|
| ZTStart | Marks the beginning of a logical transaction. |
|-----------+------------------------------------------------------------|
| $View() | Extended for examining journaling status. |
+------------------------------------------------------------------------+
2 Alias_Variables_Extensions
Alias Variables Extensions
Alias variables provide a layer of abstraction between the name of a local
variable and an array analogous to that provided by M pass by reference in
routines and function calls. Multiple local variables can be aliased to
the same array, and a SET or KILL to one acts as a SET or KILL to all.
Alias container variables provide a way of associating a reference to an
entire local variable array with a data-cell, which protects the
associated array even when it's not accessible through any current local
variable name.
GT.M aliases provide low level facilities on which an application can
implement object-oriented techniques. An object can be mapped onto, and
stored and manipulated in an array, then saved in an alias container
variable whence it can be retrieved for processing. The use of appropriate
subscripts in the array used for a container, provides a way to organize
the stored objects and retrieve them by using the $ORDER() function to
traverse the container array. The use of alias variables to implement
objects provides significant efficiencies over traditional local variables
because alias variables and alias container variables eliminate the need
to execute MERGE commands to move objects.
Example:
GTM>kill A,B
GTM>set A=1,*B=A ; B & A are aliases
GTM>write B
1
GTM>
The following table summarizes Alias Variables extensions.
+------------------------------------------------------------------------+
| GT.M Extensions for Alias Variables |
|------------------------------------------------------------------------|
| EXTENSION | EXPLANATION |
|----------------------+-------------------------------------------------|
| Set * | Explicitly creates an alias. |
|----------------------+-------------------------------------------------|
| Kill * | Removes the association between its arguments, |
| | and any associated arrays. |
|----------------------+-------------------------------------------------|
| | When QUIT * terminates an extrinsic function or |
| | an extrinsic special variable, it always |
| Quit * | returns an alias container. For more |
| | information, refer to the description of QUIT * |
| | in "Quit". |
|----------------------+-------------------------------------------------|
| ZWrite / ZSHow "V" | Produces Alias Variables format output. |
|----------------------+-------------------------------------------------|
| New | For the scope of the NEW, a NEW of a name |
| | suspends its alias association. |
|----------------------+-------------------------------------------------|
| | Create a scope in which only one association |
| Exclusive New | between an lname or an lvn and an array may be |
| | visible. |
|----------------------+-------------------------------------------------|
| | returns a unique identifier (handle) for the |
| $ZAHandle() | array associated with an lname or an alias |
| | container; for an subscripted lvn, it returns |
| | an empty string. |
|----------------------+-------------------------------------------------|
| | Extends $DATA() to reflects the current alias |
| $ZDATA() | state of the lvn or lname argument to identify |
| | alias and alias container variables. |
|----------------------+-------------------------------------------------|
| View and $View() | |
|----------------------+-------------------------------------------------|
| | TSTART command can optionally list names whose |
| | arrays are restored on a transaction RESTART. |
| TSTART, RESTART, and | If any of these are alias variables or have |
| ROLLBACK | nodes which are alias container variables, |
| | their associations are also restored on |
| | transaction RESTART. |
+------------------------------------------------------------------------+
3 SET_*_and_QUIT_*_Examples
SET * and QUIT * Examples
The following table show the type of data movement of alias and alias
container variables from QUIT * in a function to a SET * target:
+-------------------------------------------------------------------------+
| | QUIT * | SET * | Result |ZWRITE |
|----------------------+----------+-------------------+-----------+-------|
| |Creates an|Dereferences the |Same as set| |
|set *a=$$makealias(.c)|alias |alias container |*a=c |*c=a |
| |container | | | |
|----------------------+----------+-------------------+-----------+-------|
|set |Creates an|Dereferences the |Same as set| |
|*a(1)=$$makealias(.c) |alias |alias container |*a(1)=c |*a(1)=c|
| |container | | | |
|----------------------+----------+-------------------+-----------+-------|
| |Returns an|Copies the alias |Same as set| |
|set *a=$$makecntnr(.c)|alias |container |*a=c(1) |*c=a |
| |container | | | |
|----------------------+----------+-------------------+-----------+-------|
|set |Returns an|Copies the alias |Same as set| |
|*a(1)=$$makecntnr(.c) |alias |container |*a(1)=c(1) |*a(1)=c|
| |container | | | |
+-------------------------------------------------------------------------+
The makealias function returns an alias of the argument:
makealias(var)
quit *var
The makecntr function returns an alias container of the argument:
makecntnr(var)
new cont
set *cont(1)=var
quit *cont(1)
3 Examples
Examples
Example
GTM>Set A=1,*B=A ; Create an array and an association
GTM>ZWRite ; Show that the array and association exist
A=1 ;*
*B=A
GTM>Kill *A ; Remove the association for A - it now has no association and no array
GTM>ZWRite ; B is a traditional local variable
B=1
Example:
GTM>Set A=2 ; add a value for A
GTM>ZWRite ; A and B have different values and both are traditional local variables
A=2
B=1
GTM>
KILL on the other hand, removes data in the array (and possibly the array
itself) without affecting any alias association.
GTM>Set A=2,*B=A ; Create an array and an association
GTM>ZWRite ; Both array and association exist
A=2 ;*
*B=A
GTM>Kill A ; Kill the array
GTM>ZWRite ; There's no data to show - only the association
*B=A
GTM>Set B=3 ; Create a new value
GTM>ZWRite ; The association was unaffected by the Kill
A=3 ;*
*B=A
GTM>
Example:
$ /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^killalias
killalias ; Demonstrate Kill * of pass-by-reference
ZPrint ; Print this program
Set A=1,C=3
Write "------------",!
Write "Initial Values:",!
ZWRite
Do K1(.A,.C) ; Pass A & C by reference
Write "------------",!
Write "Value of A is unchanged because of Kill *B, but C has changed: ",!
ZWRite
Quit
;
K1(B,D) ; A & C are bound to B & D respectively
Write "------------",!
Write "A & B are aliases, as are C & D:",!
ZWRite
Kill *B
Set B=2,D=4
Write "------------",!
Write "After Kill *B, A & B are different but C & D remain associated:",!
ZWrite
Quit
------------
Initial Values:
A=1
C=3
------------
A & B are aliases, as are C & D:
A=1 ;*
*B=A
C=3 ;*
*D=C
------------
After Kill *B, A & B are different but C & D remain associated:
A=1
B=2
C=4 ;*
*D=C
------------
Value of A is unchanged because of Kill *B, but C has changed:
A=1
C=4
Example:
GTM>Set A=1,*B=A ; Create an array and association
GTM>ZWRite ; Verify that it's there
A=1 ;*
*B=A
GTM>Kill (A) ; Kill everything except A
GTM>ZWRite ; Demonstrate that A also has no array
GTM>Set A=2 ; Create an array
GTM>ZWRite ; The association survived the Kill
A=2 ;*
*B=A
GTM>
3 Examples
Examples
Example:
$ /usr/lib/fis-gtm/V5.4-002B/gtm -run ^tprestart
tprestart ; Transaction restart variable association also restored on restart
zprint ; Print this program
set A="Malvern",C="Pennsylvania",E="USA"
set *B=C,*D(19355)=E
write "------------",!
write "Initial values & association",!
zwrite
tstart (B,D) ; On restart: A not restored, B,D restored, C,E restored by association
if '$TRestart Do ; Change C,E if first time through
.set C="Wales",E="UK"
.kill *D(19355)
.write "------------",!
.write "First time through transaction; B,C,D,E changed",!
.zwrite
.set A="Brynmawr"
.kill *B
.write "------------",!
.write "A changed; association between B & C and D & E killed; B,D have no value",!
.zwrite
.trestart
else Do ; Show restored values on restart
write "------------",!
write "Second time through transaction; B,C,D,E & association restored",!
zwrite
tcommit ; No global updates in this transaction!
quit
------------
Initial values & association
A="Malvern"
B="Pennsylvania" ;*
*C=B
*D(19355)=E
E="USA" ;*
------------
First time through transaction; B,C,D,E changed
A="Malvern"
B="Wales" ;*
*C=B
E="UK" ;*
------------
A changed; association between B & C and D & E killed; B,D have no value
A="Brynmawr"
C="Wales" ;*
E="UK" ;*
------------
Second time through transaction; B,C,D,E & association restored
A="Brynmawr"
B="Pennsylvania" ;*
*C=B
*D(19355)=E
E="USA" ;*
Note that TROLLBACK does not restore alias variables:
/usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^tprollback
tprollback ;
zprint ; Print this program
set A(1)=1,A(2)=2,A(3)=3
set B(1)="1b",*B(2)=A,B(3)=3 ; B includes a container for A
set *C(1)=B ; C includes a container for B
kill *A,*B ; C is the only way to the data
write "------------",!
write "Only containers before transaction:",!
zwrite
tstart (C)
if '$trestart
.set *D=C(1) ; D is now an alias for what used to be B
.set D(3)=-D(3)
.set *D=D(2) ; D is now an alias for what used to be A
.set D(1)=-D(1)
.kill *D ; Kill D after is used to manipulate the arrays
.write "------------",!
.write "Changed values before restart:",!
.zwrite
.trestart
write "------------",!
write "Restored values restart:",!
zwrite
kill C ; Kill only handle to arrays
write "------------",!
write "No local arrays left:",!
zwrite
trollback ; Rollback transaction, don't commit it
write "------------",!
write "Rollback doesnt restore names and local arrays",!
zwrite
quit
------------
Only containers before transaction:
$ZWRTAC=""
*C(1)=$ZWRTAC1
$ZWRTAC1(1)="1b"
*$ZWRTAC1(2)=$ZWRTAC2
$ZWRTAC2(1)=1
$ZWRTAC2(2)=2
$ZWRTAC2(3)=3
$ZWRTAC1(3)=3
$ZWRTAC=""
------------
Restored values restart:
$ZWRTAC=""
*C(1)=$ZWRTAC1
$ZWRTAC1(1)="1b"
*$ZWRTAC1(2)=$ZWRTAC2
$ZWRTAC2(1)=1
$ZWRTAC2(2)=2
$ZWRTAC2(3)=3
$ZWRTAC1(3)=3
$ZWRTAC=""
------------
No local arrays left:
------------
Rollback doesnt restore names and local arrays
Example:
$ /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^aliasexample; Extended annotated alias example
zprint
write "------------",!
set x="name level",x(1)=1,x(1,2)="1,2",x("foo")="bar"
write $ZDATA(x),! ; x is a conventional lvn - output 11
set *y=x ; x an y are now alias variables
write $ZDATA(x),! ; output appears as 111
set *a(1)=y ; a(1) is now an alias container variable
set b="bness",b("b")="bbness" ; b is a conventional lvn
set *b=a(1) ; b joins x and y as alias variables for the same data
; prior b values are lost
; set *<name> is equivalent to Kill *<name> Set *<name>
set y("hi")="sailor" ; Assignment applies to all of {b,x,y}
kill b("foo") ; Kill applies to all of {b,x,y}
kill *x ; x is undefined and no longer an alias variable
; b and y still provide access to the data
write a(1),"<",! ; output appears as <
write a(1)*3,! ; output appears as 0
write $length(a(1)),! ; output appears as 0
set c=y,c("legs")="tars" ; c is conventional lvn with value "name level"
do sub1
write $Data(c),! ; output is 1
do sub2(.c)
set a(1)="" ; a(1) ceases to be an alias container variable
; has the value ""
write $D(i),! ; output is 0
kill *c,*y ; c and y become undefined lvns
zwrite b ; output is b("got")="a match"
; it's no longer an alias variable
; as everything else has gone
quit
sub1
new y ; in this scope y is no longer an alias for b
set *y=c ; in this scope c and y are alias variables
kill y("legs") ; Kill apples to all of {c,y}
kill *y ; in this scope y is no longer an alias for c
; this is really redundant as
; the Quit implicitly does the same thing
quit
sub2(i) ; i and c are joined due to pass-by-reference
write $ZAHandle(c)=$ZAHandle(i),! ; output appears as 1
kill b ; data for {b,y} is gone
; both are undefined, but remain alias variables
set *c=a(1) ; c joins {b,y} as alias variable; prior value of c lost
; c is no longer alias of i
write $ZAHandle(c)=$ZAHandle(i),! ; output appears as 0
set i=a(1) ; Assignment applies to i - value is ""
wet c("got")="a match" ; Assignment applies to all of {b,c,y)
quit
------------
11
111
<
0
0
1
1
0
0
b("got")="a match"
2 Extensions_for_Unicode(TM)_support
Extensions for Unicode(TM) support
To represent and process strings that use international characters, GT.M
processes can use Unicode.
If the environment variable gtm_chset has a value of UTF-8 and either
LC_ALL or LC_CTYPE is set to a locale with UTF-8 support (for example,
zh_CN.utf8), a GT.M process interprets strings as containing characters
encoded in the UTF-8 representation. In the UTF-8 mode, GT.M no longer
assumes that one character is one byte, or that the glyph display width of
a character is one. Depending on how ICU is built on a computer system, in
order to operate in UTF-8 mode, a GT.M process may well also need a third
environment variable, gtm_icu_version set appropriately.
If the environment variable gtm_chset has no value, the string "M", or any
value other than "UTF-8", GT.M treats each 8-bit byte as a character,
which suffices for English, and many single-language applications.
All GT.M components related to M mode reside in the top level directory in
which a GT.M release is installed and the environment variable gtm_dist
should points to that directory for M mode processes. All Unicode-related
components reside in the utf8 subdirectory and the environment variable
gtm_dist should point to that subdirectory for UTF-8 mode processes. So,
in addition to the values of the environment variables gtm_chset and
LC_ALL/LC_CTYPE, gtm_dist for a UTF-8 process should also point to the
utf8 subdirectory.
M mode and UTF-8 mode are set for the process, not for the database. As a
subset of Unicode, ASCII characters ($CHAR() values 0 through 127) are
interpreted identically by processes in M and UTF-8 modes. The indexes and
values in the database are simply sequences of bytes and therefore it is
possible for one process to interpret a global node as encoded in UTF-8
and for another to interpret the same node as bytecodes. Note that such an
application configuration would be extremely unusual, except perhaps
during a transition phase or in connection with data import/export.
In UTF-8 mode, string processing functions (such as $EXTRACT()) operate on
strings of multi-byte characters, and can therefore produce different
results in M and UTF-8 modes, depending on the actual data processed,
Each function has a "Z" alter ego (for example, $ZEXTRACT()) that can be
used to operate on sequences of bytes identically in M and UTF-8 modes
(that is, in M mode, $EXTRACT() and $ZEXTRACT() behave identically).
In M mode, the concept of an illegal character does not exist. In UTF-8
mode, a sequence of bytes may not represent a valid character, and
generates an error when encountered by functions that expect and process
UTF-8 strings. During a migration of an application to add support for
Unicode, illegal character errors may be frequent and indicative of
application code that is yet to be modified. VIEW "NOBADCHAR" suppresses
these errors at times when their presence impedes development.
In UTF-8 mode, GT.M also supports IO encoded in UTF-16 variants as well as
in the traditional one byte per character encoding from devices other than
$PRINCIPAL.
The following table summarizes GT.M Unicode support.
+------------------------------------------------------------------------+
| EXTENSION | EXPLANATION |
|------------------------+-----------------------------------------------|
| | IN UTF-8 mode, the $ASCII() function returns |
| | the integer Unicode code-point value of a |
| | character in the given string. Note that the |
| $ASCII() | name $ASCII() is somewhat anomalous for |
| | Unicode data but that name is the logical |
| | extension of the function from M mode to |
| | UTF-8 mode. |
|------------------------+-----------------------------------------------|
| | In UTF-8 mode, $CHAR() returns a string |
| $Char() | composed of characters represented by the |
| | integer equivalents of the Unicode |
| | code-points specified in its argument(s). |
|------------------------+-----------------------------------------------|
| $Extract() | The $EXTRACT() function returns a substring |
| | of a given string. |
|------------------------+-----------------------------------------------|
| | The $FIND() function returns an integer |
| $Find() | character position that locates the |
| | occurrence of a substring within a string. |
|------------------------+-----------------------------------------------|
| $Justify() | The $JUSTIFY function returns a formatted |
| | string. |
|------------------------+-----------------------------------------------|
| | The $LENGTH() function returns the length of |
| $Length() | a string measured in characters, or in |
| | "pieces" separated by a delimiter specified |
| | by its optional second argument. |
|------------------------+-----------------------------------------------|
| | The $PIECE() function returns a substring |
| $Piece() | delimited by a specified string delimiter |
| | made up of one or more characters. |
|------------------------+-----------------------------------------------|
| | The $TRANSLATE() function returns a string |
| | that results from replacing or dropping |
| $TRanslate() | characters in the first of its arguments as |
| | specified by the patterns of its other |
| | arguments. |
|------------------------+-----------------------------------------------|
| | For UTF-8 mode and TRM and SD output, $X |
| $X | increases by the display-columns (width in |
| | glyphs) of a given string that is written to |
| | the current device. |
|------------------------+-----------------------------------------------|
| | The $ZASCII() function returns the numeric |
| $ZASCII() | byte value (0 through 255) of a given |
| | sequence of octets (8-bit bytes). |
|------------------------+-----------------------------------------------|
| | The read-only intrinsic special variable |
| | $ZCHSET takes its value from the environment |
| | variable gtm_chset. An application can obtain |
| $ZCHset | the character set used by a GT.M process by |
| | the value of $ZCHSET. $ZCHSET can have only |
| | two values "M", or "UTF-8" and it cannot |
| | appear on the left of an equal sign in the |
| | SET command. |
|------------------------+-----------------------------------------------|
| | The $ZCHAR() function returns a byte sequence |
| $ZCHar() | of one or more bytes corresponding to numeric |
| | byte value (0 through 255) specified in its |
| | argument(s). |
|------------------------+-----------------------------------------------|
| | The $ZCONVERT() function returns its first |
| | argument as a string converted to a different |
| $ZCOnvert() | encoding. The two argument form changes the |
| | encoding for case within a character set. The |
| | three argument form changes the encoding |
| | scheme. |
|------------------------+-----------------------------------------------|
| | The $ZEXTRACT() function returns a byte |
| $ZExtract() | sequence of a given sequence of octets (8-bit |
| | bytes). |
|------------------------+-----------------------------------------------|
| | The $ZFIND() function returns an integer byte |
| $ZFind() | position that locates the occurrence of a |
| | byte sequence within a sequence of |
| | octets(8-bit bytes). |
|------------------------+-----------------------------------------------|
| $ZJustify() | The $JUSTIFY() function returns a formatted |
| | and fixed length byte sequence. |
|------------------------+-----------------------------------------------|
| | The $ZLENGTH() function returns the length of |
| $ZLength() | a sequence of octets measured in bytes, or in |
| | "pieces" separated by a delimiter specified |
| | by its optional second argument. |
|------------------------+-----------------------------------------------|
| | ZPATN[UMERIC] is a read-only intrinsic |
| | special variable that determines how GT.M |
| | interprets the patcode N used in the pattern |
| | match operator. With $ZPATNUMERIC="UTF-8", |
| $ZPATNumeric | the patcode N matches any numeric character |
| | as defined by Unicode. By default patcode N |
| | only matches the ASCII digits, which are the |
| | only digits which M actually treats as |
| | numerics. |
|------------------------+-----------------------------------------------|
| | The $ZPIECE() function returns a sequence of |
| | bytes delimited by a specified byte sequence |
| $ZPiece() | made up of one or more bytes. In M, $ZPIECE() |
| | typically returns a logical field from a |
| | logical record. |
|------------------------+-----------------------------------------------|
| | $ZPROM[PT] contains a string value specifying |
| | the current Direct Mode prompt. By default, |
| | GTM> is the Direct Mode prompt. M routines |
| | can modify $ZPROMPT by means of a SET |
| | command. $ZPROMPT cannot exceed 31 bytes. If |
| | an attempt is made to assign $ZPROMPT to a |
| $ZPROMpt | longer string, GT.M takes only the first 31 |
| | bytes and truncates the rest. With character |
| | set UTF-8 specified, if the 31st byte is not |
| | the end of a valid UTF-8 character, GT.M |
| | truncates the $ZPROMPT value at the end of |
| | last character that completely fits within |
| | the 31 byte limit. |
|------------------------+-----------------------------------------------|
| $ZSUBstr() | The $ZSUBSTR() function returns a properly |
| | encoded string from a sequence of bytes. |
|------------------------+-----------------------------------------------|
| | The $ZTRANSLATE() function returns a byte |
| | sequence that results from replacing or |
| $ZTRanslate() | dropping bytes in the first of its arguments |
| | as specified by the patterns of its other |
| | arguments. $ZTRANSLATE() provides a tool for |
| | tasks such as encryption. |
|------------------------+-----------------------------------------------|
| | The $ZWIDTH() function returns the numbers of |
| $ZWidth() | columns required to display a given string on |
| | the screen or printer. |
|------------------------+-----------------------------------------------|
| | The GT.M %HEX2UTF utility returns the GT.M |
| | encoded character string from the given |
| %HEX2UTF | bytestream in hexadecimal notation. This |
| | routine has entry points for both interactive |
| | and non-interactive use. |
|------------------------+-----------------------------------------------|
| | The GT.M %UTF2HEX utility returns the |
| | hexadecimal notation of the internal byte |
| %UTF2HEX | encoding of a UTF-8 encoded GT.M character |
| | string. This routine has entry points for |
| | both interactive and non-interactive use. |
|------------------------+-----------------------------------------------|
| | Enables or disables automatic record |
| | termination. When the current record size |
| [NO]WRAP (USE) | ($X) reaches the maximum WIDTH and the device |
| | has WRAP enabled, GT.M starts a new record, |
| | as if the routine had issued a WRITE ! |
| | command. |
|------------------------+-----------------------------------------------|
| | In UTF-8 mode, DSE and LKE accept characters |
| | in Unicode in all their command qualifiers |
| DSE and LKE | that require file names, keys, or data (such |
| | as DSE -KEY, DSE -DATA and LKE -LOCK |
| | qualifiers). |
|------------------------+-----------------------------------------------|
| | GDE allows the name of a file to include |
| | characters in Unicode |
| GDE Objects | |
| | In UTF-8 mode, GDE considers a text file to |
| | be encoded in UTF-8 when it is executed via |
| | the "@" command. |
|------------------------+-----------------------------------------------|
| | Specifies character filtering for specified |
| | cursor movement sequences on devices where |
| | FILTER applies. |
| | |
| | In UTF-8 mode, the usual Unicode line |
| FILTER[=expr] | terminators (U+000A (LF), U+0000D (CR), |
| | U+000D followed by U+000A (CRLF), U+0085 |
| | (NEL), U+000C (FF), U+2028 (LS) and U+2029 |
| | (PS)) are recognized. If FILTER=CHARACTER is |
| | enabled, all of the terminators are |
| | recognized to maintain the values of $X and |
| | $Y. |
|------------------------+-----------------------------------------------|
| | The Job command spawns a background process |
| | with the same environment as the M process |
| | doing the spawning. Therefore, if the parent |
| | process is operating in UTF-8 mode, the Job'd |
| Job | process also operates in UTF-8 mode. In the |
| | event that a background process must have a |
| | different mode from the parent, create a |
| | shell script to alter the environment as |
| | needed, and spawn it with a ZSYstem command |
| | or start it as a PIPE device. |
|------------------------+-----------------------------------------------|
| | MUPIP EXTRACT |
| | |
| | In UTF-8 mode, MUPIP EXTRACT, MUPIP JOURNAL |
| | -EXTRACT and MUPIP JOURNAL -LOSTTRANS write |
| | sequential output files in the UTF-8 |
| | character encoding form. For example, in |
| | UTF-8 mode if ^A has the value of |
| | ************, the sequential output file of |
| | the MUPIP EXTRACT command is: |
| | |
| | 09-OCT-2006 04:27:53 ZWR |
| | |
| | GT.M MUPIP EXTRACT UTF-8 |
| | |
| MUPIP | ^A="************" |
| | |
| | MUPIP LOAD |
| | |
| | MUPIP LOAD command considers a sequential |
| | file as encoded in UTF-8 if the environment |
| | variable gtm_chset is set to UTF-8. Ensure |
| | that MUPIP EXTRACT commands and corresponding |
| | MUPIP LOAD commands execute with the same |
| | setting for the environment variable |
| | gtm_chset. The M utility programs %GO and %GI |
| | have the same requirement for mode matching. |
| | For more information on MUPIP EXTRACT and |
| | MUPIP LOAD, refer to the General Database |
| | Management chapter in GT.M Administration and |
| | Operations Guide. |
|------------------------+-----------------------------------------------|
| | In UTF-8 mode, the OPEN command recognizes |
| Open | ICHSET, OCHSET, and CHSET as three additional |
| | deviceparameters to determine the encoding of |
| | the input / output devices. |
|------------------------+-----------------------------------------------|
| | GT.M allows the pattern string literals to |
| Pattern Match Operator | contain the characters in Unicode. |
| (?) | Additionally, GT.M extends the M standard |
| | pattern codes (patcodes) A, C, N, U, L, P and |
| | E to the Unicode character set. |
|------------------------+-----------------------------------------------|
| | In UTF-8 mode, the READ command uses the |
| | character set value specified on the device |
| | OPEN as the character encoding of the input |
| | device. If character set "M" or "UTF-8" is |
| | specified, the data is read with no |
| | transformation. If character set is "UTF-16", |
| Read | "UTF-16LE", or "UTF-16BE", the data is read |
| | with the specified encoding and transformed |
| | to UTF-8. If the READ command encounters an |
| | illegal character or a character outside the |
| | selected representation, it triggers a |
| | run-time error. The READ command recognizes |
| | all Unicode line terminators for non-FIXED |
| | devices. |
|------------------------+-----------------------------------------------|
| | When a number sign (#) and a non-zero integer |
| | expression immediately follow the variable |
| | name, the integer expression determines the |
| | maximum number of characters accepted as the |
| | input to the READ command. In UTF-8 or UTF-16 |
| Read # | modes, this can occur in the middle of a |
| | sequence of combining code-points (some of |
| | which are typically non-spacing). When this |
| | happens, any display on the input device, may |
| | not represent the characters returned by the |
| | fixed-length READ (READ #). |
|------------------------+-----------------------------------------------|
| | In UTF-8 or UTF-16 modes, the READ * command |
| Read * | accepts one character in Unicode of input and |
| | puts the numeric code-point value for that |
| | character into the variable. |
|------------------------+-----------------------------------------------|
| | As an aid to migrating applications to |
| | Unicode, this UTF-8 mode VIEW command |
| View "[NO]BADCHAR" | determines whether Unicode enabled functions |
| | trigger errors when they encounter illegal |
| | strings. |
|------------------------+-----------------------------------------------|
| | For some languages (such as Chinese), the |
| | ordering of strings according to Unicode |
| | code-points (character values) may not be the |
| | linguistically or culturally correct |
| | ordering. Supporting applications in such |
| User-defined Collation | languages requires development of collation |
| | modules - GT.M natively supports M collation, |
| | but does not include pre-built collation |
| | modules for any specific natural language. |
| | Therefore, applications that use characters |
| | in Unicode may need to implement their own |
| | collation functions. |
|------------------------+-----------------------------------------------|
| | When ICHSET is UTF-16, GT.M uses BOM (U+FEFF) |
| | to automatically determine the endianess. For |
| | this to happen, the BOM must appear at the |
| | beginning of the file or data stream. If BOM |
| | is not present, GT.M assumes big endianess. |
| | SEEK or APPEND operations require specifying |
| | the endianess (UTF-16LE or UTF-16BE) because |
| | they do not go to the beginning of the file |
| | or data stream to automatically determine the |
| | endianess. When endianess is not specified, |
| | SEEK or APPEND assume big endianess. |
| | |
| Unicode Byte Order | If the character set of a device is UTF-8, |
| Marker (BOM) | GT.M checks for and ignores a BOM on input. |
| | |
| | If the BOM does not match the character set |
| | specified at device OPEN, GT.M produces an |
| | error. READ does not return BOM to the |
| | application and the BOM is not counted as |
| | part of the first record. |
| | |
| | If the output character set for a device is |
| | UTF-16 (but not UTF-16BE or UTF-16LE,) GT.M |
| | writes a BOM before the initial output. The |
| | application code does not need to explicitly |
| | write the BOM. |
|------------------------+-----------------------------------------------|
| | In UTF-8 mode and TRM and SD output, the |
| | WIDTH deviceparameter specifies the |
| WIDTH=intexpr (USE) | display-columns and is used with $X to |
| | control truncation and WRAPing of the visual |
| | representation of the stream. |
|------------------------+-----------------------------------------------|
| | In UTF-8 mode, the WRITE command uses the |
| | character set specified on the device OPEN as |
| | the character encoding of the output device. |
| | If character set specifies "M" or "UTF-8", |
| Write | GT.M WRITEs the data with no transformation. |
| | If character set specifies "UTF-16", |
| | "UTF-16LE" or "UTF-16BE", the data is assumed |
| | to be encoded in UTF-8 and WRITE transforms |
| | it to the character encoding specified by |
| | character set device parameter. |
|------------------------+-----------------------------------------------|
| | When the argument of a WRITE command consists |
| | of a leading asterisk (*) followed by an |
| Write * | integer expression, the WRITE command outputs |
| | the character represented by the code-point |
| | value of that integer expression. |
|------------------------+-----------------------------------------------|
| | In UTF-8 mode, the ZSHOW command exhibits |
| | byte-oriented and display-oriented behavior |
| | as follows: |
| | |
| | 1. ZSHOW targeted to a device (ZSHOW "*") |
| | aligns the output according to the |
| | numbers of display columns specified by |
| | the WIDTH deviceparameter. |
| ZSHow | 2. ZSHOW targeted to a local (ZSHOW "*":lcl) |
| | truncates data exceeding 2048KB at the |
| | last character that fully fits within the |
| | 2048KB limit. |
| | 3. ZSHOW targeted to a global (ZSHOW |
| | "*":^CC) truncates data exceeding the |
| | maximum record size for the target global |
| | at the last character that fully fits |
| | within that record size. |
+------------------------------------------------------------------------+
3 ICU
ICU
While GT.M provides a framework for handling characters in Unicode, it
relies on the ICU (International Components for Unicode) library for
language specific information.
ICU is a widely used, defacto standard package (see http://icu-project.org
for more information) that GT.M relies on for most operations that require
knowledge of the Unicode character sets, such as text boundary detection,
character string conversion between UTF-8 and UTF-16, and calculating
glyph display widths.
**Important**
Unless Unicode support is sought for a process (that is, unless the
environment variable gtm_chset is UTF8"), GT.M processes do not need ICU.
In other words, existing, non-Unicode, applications continue to work on
supported platforms without ICU.
An ICU version number is of the form major.minor.milli.micro where major,
minor, milli and micro are integers. Two versions that have different
major and/or minor version numbers can differ in functionality and API
compatibility is not guaranteed. Differences in milli or micro versions
are maintenance releases that preserve functionality and API
compatibility. ICU reference releases are defined by major and minor
version numbers. Note that display widths for some characters changed in
ICU 4.0 and may change again in the future, as both languages and ICU
evolve.
An operating system's distribution generally includes an ICU library
tailored to the OS and hardware, therefore FIS does not provide any ICU
library. In order to support Unicode functionality, GT.M requires an
appropriate version of ICU to be installed on the system - check the
release notes for your GT.M release for supported ICU versions.
GT.M expects ICU to be compiled with symbol renaming disabled and will
issue an error at startup if the available version of ICU is built with
symbol renaming enabled. To use a version of ICU built with symbol
renaming enabled, the $gtm_icu_version environment variable indicates the
MAJOR VERSION and MINOR VERSION numbers of the desired ICU formatted as
MajorVersion.MinorVersion (for example "3.6" to denote ICU-3.6). When
$gtm_icu_version is so defined, GT.M attempts to open the specific version
of ICU. In this case, GT.M works regardless of whether or not symbols in
this ICU have been renamed. A missing or ill-formed value for this
environment variable causes GT.M to only look for non-renamed ICU symbols.
The release notes for each GT.M release identify the required reference
release version number as well as the milli and micro version numbers that
were used to test GT.M prior to release. In general, it should be safe to
use any version of ICU with the specific ICU reference version number
required and milli and micro version numbers greater than those identified
in the release notes for that GT.M version.
ICU supports multiple threads within a process, and an ICU binary library
can be compiled from source code to either support or not support multiple
threads. In contrast, GT.M does not support multiple threads within a GT.M
process. On some platforms, the stock ICU library, which is usually
compiled to support multiple threads, may work unaltered with GT.M. On
other platforms, it may be required to rebuild ICU from its source files
with support for multiple threads turned off. Refer to the release notes
for each GT.M release for details about the specific configuration tested
and supported. In general, the GT.M team's preference for ICU binaries
used for each GT.M version are, in decreasing order of preference:
1. The stock ICU binary provided with the operating system distribution.
2. A binary distribution of ICU from the download section of the ICU
project page.
3. A version of ICU locally compiled from source code provided by the
operating system distribution with a configuration disabling
multi-threading.
4. A version of ICU locally compiled from the source code from the ICU
project page with a configuration disabling multi-threading.
GT.M uses the POSIX function dlopen() to dynamically link to ICU. In the
event you have other applications that require ICU compiled with threads,
place the different builds of ICU in different locations, and use the
dlopen() search path feature (for example, the LD_LIBRARY_PATH environment
variable on Linux) to enable each application to link with its appropriate
ICU.
4 Compiling_ICU
Compiling ICU
To compile ICU, refer to the Compiling ICU Appendix in the GT.M
Administration and Operations Guide and to the release notes of your GT.M
release.
1 Program_Cycle
Program Cycle
In contrast to M environments that interpret M code, GT.M compiles M code
from source files into the target machine language. The GT.M compiler
produces object files, which are dynamically linked into an image. Source
files and object files may be managed independently, or placed together in
a specific directory. GT.M permits access to source and object files in
multiple directories.
GT.M databases are UNIX files identified by a small file called a Global
Directory. Global Directories allow management of the database files to be
independent of the placement of files containing M routines. By changing
the Global Directory, you can use the same programs to access different
databases.
Program development may utilize both GT.M and UNIX development tools. The
development methodology and environment chosen for a particular
installation, and tailored by the individual user, determines the actual
mix of tools. These tools may vary from entirely GT.M with little UNIX, to
mostly UNIX with a modest use of GT.M.
Direct Mode serves as an interactive interface to the GT.M run-time
environment and the compiler. In Direct Mode, the user enters M commands
at the GT.M prompt, and GT.M compiles and executes the command. This
feature provides immediate turnaround for rapid program development and
maintenance.
2 Compile_Source_Program
Compile Source Program
If you wish to focus on program development outside the GT.M environment,
skip the next section and continue with the section "Compiling from the
Shell".
GT.M compiles M source code files and produces object files for complete
integration into the UNIX enviroment. The object modules have the same
name as the compiled M source file with an .o file extension, unless
otherwise specified. The object files contain machine instructions and
information necessary to connect the routine with other routines, and map
it into memory. An M routine source file must be compiled after it is
created or modified. You can compile explicitly with the ZLINK command or
implicitly with auto-ZLINK. At the shell command line, compile by issuing
the mumps command.
The compiler checks M code for syntax errors and displays error messages
on the terminal, when processing is complete. Each error message provides
the source line in error with an indicator pointing to the place on the
line where the error is occurring. For a list and description of the
compiler error messages, refer to the GT.M Message and Recovery Procedures
Reference Manual.
You can generate a listing file containing the compile results by
including the -list qualifier as a modifier to the argument to the ZLINK
command in Direct Mode. This can also be done by redirecting the compiler
messages to a file by adding >filename 2>&1 to the mumps command when
compiling a program from the shell. See "Compile from the Shell"
for an explanation of the M command describing -list, and other valid
qualifiers for the M and ZLINK commands.
The compiler stops processing a routine line when it detects an error on
that line. Under most conditions the compiler continues processing the
remaining routine lines. This allows the compiler to produce a more
complete error analysis of the routine and to generate code that may have
valid executable paths. The compiler does not report multiple syntax
errors on the same line. When it detects more than 127 syntax errors in a
source file, the compiler ceases to process the file.
3 Compile
Compile
In Direct Mode, GT.M provides access to the compiler explicitly through
the ZLINK and ZCOMPILE commands, and implicitly through automatic
invocation of ZLINK functionality (auto-ZLINK) to add required routines to
the image. ZCOMPILE is a GT.M routine compilation command, it compiles the
routine and creates a new object module. The primary task of ZLINK is to
place the object code in memory and "connect" it with other routines.
However, under certain circumstances, ZLINK may first use the GT.M
compiler to create a new object module.
The difference between ZCOMPILE and ZLINK is that ZCOMPILE creates a new
object module on compiling, whereas the ZLINK command links the object
module with other routines and places the object code in memory.
ZLINK compiles under these circumstances:
* ZLINK cannot locate a copy of the object module but can locate a copy
of the source module.
* ZLINK can locate both object and source module, and finds the object
module to be older than the source module.
* The file-specification portion of the ZLINK argument includes an
explicit extension of .m.
Auto-ZLINK compiles under the first two circumstances, but can never
encounter the last one.
When a command refers to an M routine that is not part of the current
image, GT.M automatically attempts to ZLINK and, if necessary, compile
that routine. In Direct Mode, the most common method to invoke the
compiler through an auto-ZLINK is to enter DO ^routinename at the GTM>
prompt. When the current image does not contain the routine, GT.M does the
following:
By using the DO command, you implicitly instruct GT.M to compile, link,
and execute the program. With this method, you can test your routine
interactively.
Example:
GTM>do ^payroll
GTM>do ^taxes
This uses the M DO command to invoke the GT.M compiler implicitly from the
GTM> prompt if the routine requires new object code. When the compiler
runs, it produces two object module files, payroll.o and taxes.o.
If you receive error messages from the compilation, you may fix them
immediately by returning to the editor and correcting the source. By
default, the GT.M compiler operates in "compile-as-written" mode, and
produces object code even when a routine contains syntax errors. This code
includes all lines that are correct and all commands on a line with an
error, up to the error. Therefore, you may decide to tailor the debugging
cycle by running the program without removing the syntax errors.
**Caution**
The DO command does not add an edited routine to the current image if the
image already includes a routine matching the DO argument routine name.
When the image contains a routine, GT.M simply executes the routine
without examining whether a more recent version of the module exists. If
you have a routine in your image, and you wish to change it, you must
explicitly ZLINK that routine.
Example:
GTM>zlink "payroll"
GTM>zlink "taxes.m"
The first ZLINK compiles payroll.m if it cannot locate payroll, or if it
finds that payroll.m has a more recent date/time stamp than payroll.o. The
second ZLINK always compiles taxes.m producing a new taxes.o.
3 Compile_from_the_Shell
Compile from the Shell
From the shell, invoke the compiler by entering mumps file-name at the
shell prompt.
Example:
$ mumps payroll.m
$ mumps taxes.m
This uses the mumps command to invoke the GT.M compiler from the shell
prompt, and creates .o versions of these files.
Use the mumps command at the shell prompt to:
* Check the syntax of a newly entered program.
* Optionally, get a formatted listing of the program.
* Ensure that all object code is up to date before linking.
The mumps command invokes the compiler to translate an M source file into
object code.
The format for the MUMPS command is:
MUMPS [-qualifier[...]] pathname
The * wildcard accepts any legal combination of numbers and characters
including a null, in the position the wildcard holds.
The ? wildcard accepts exactly one legal character in its position.
For example, mumps *.m compiles all files in the current default directory
with an .m extension. mumps *pay?.m compiles .m files with names that
contain any characters followed by pay, followed by one character. Unlike
when using ZLINK or ZCOMPILE, the filename must be fully specified when
compiling from the shell.
**Caution**
When forming routine names, the compiler truncates object filenames to a
maximum length of 31 characters. For example, for a source file called
Adatabaseenginewithscalabilityproven.m the compiler generates an object
file called Adatabaseenginewithscalabilityp.o. Ensure that the first 31
characters of source file names are unique.
3 mumps_qualifiers
mumps qualifiers
The mumps command allows qualifiers that customize the type and form of
the compiler output to meet specific programming needs. MUMPS command
qualifiers may also appear as a modifier to the argument to the GT.M ZLINK
and ZCOMPILE commands. The following section describes the mumps command
qualifiers. Make sure the arguments are specified ahead of file name and
after the command itself.
4 di[rect_mode]
di[rect_mode]
Invokes a small GT.M image that immediately initiates Direct Mode.
-direct_mode does not invoke the M compiler.
The -direct_mode qualifier is incompatible with a file specification and
with all other qualifiers.
4 dy[namic_literals]
dy[namic_literals]
Compiles certain data structures associated with literals used in the
source code in a way that they are dynamically loaded and unloaded from
the object code. The dynamic loading and unloading of these data
structures:
o Reduces the amount of private memory required by each process which in
turn allows more processes to execute with the same memory.
o In some circumstances, increases application performance by making
more memory available for file system buffers.
o Increases the CPU and stack costs of local variable processing.
With no -DYNAMIC_LITERALS specified, these data structures continue to be
generated when a routine is linked and stay in the private memory of each
process. As the use of -DYNAMIC_LITERALS increases object code size, and
as the dynamic loading and unloading only saves memory when the object
code is in shared libraries, FIS recommends restricting the use of
-DYNAMIC_LITERALS only when compiling object code to be loaded into shared
libraries.
4 [no]embed_source
[no]embed_source
Instructs GT.M to embeds routine source code in the object code. The
default is NOEMBED_SOURCE. Like other GT.M compilation qualifiers, this
qualifier can be specified through the $ZCOMPILE intrinsic special
variable and gtmcompile environment variable. EMBED_SOURCE provides $TEXT
and ZPRINT access to the correct source code, even if the original M
source file has been edited or removed. Where the source code is not
embedded in the object code, GT.M attempts to locate the source code file.
If it cannot find source code matching the object code, $TEXT() returns a
null string. ZPRINT prints whatever source code found and also prints a
TXTSRCMAT message in direct mode; if it cannot find a source file, ZPRINT
issues a FILENOTFND error.
4 [no]i[gnore]
[no]i[gnore]
Instructs the compiler to produce an object file even when the compiler
detects errors in the source code (-ignore), or not to produce an object
file when the compiler encounters an error (-noignore).
When used with the -noobject qualifier, the -ignore qualifier has no
effect.
Execution of a routine that compiles with errors produces run-time errors
when the execution path encounters any of the compile time errors.
This compile-as-written mode facilitates a flexible approach to debugging
and expedites conversion to GT.M from an interpreted environment. Many M
applications from an interpreted environment contain syntax abnormalities.
This feature of compiling and later executing a routine provides the feel
of developing in an interpreted environment.
By default, the compiler operates in -ignore mode and produces an object
module even when the source routine contains errors.
4 le[ngth]=lines
le[ngth]=lines
Controls the page length of the listing file.
The M compiler ignores the -length qualifier unless it appears with the
-list qualifier.
By default, the listing has -length=66.
4 [no]li[st][=filename]
[no]li[st][=filename]
Instructs the compiler to produce a source program listing file, and
optionally specifies a name for the listing file. The listing file
contains numbered source program text lines. When the routine has errors,
the listing file also includes an error count, information about the
location, and the cause of the errors.
When you do not specify a file name for the listing file, the compiler
produces a listing file with the same name as the source file with a .lis
file extension.
The -length and -space qualifiers modify the format and content of the
listing file. The M compiler ignores these qualifiers unless the command
includes the -list qualifier.
By default, the compiler operates -nolist and does not produce listings.
4 noin[line_literals]
noin[line_literals]
Compiles routines to use library code in order to load literals instead of
generating in-line code thereby reducing the routine size. At the cost of
a small increase in CPU, the use of -NOINLINE_LITERAL may help counteract
growth in object size due to -DYNAMIC_LITERALS.
**Important**
Both -DYNAMIC_LITERALS and -NOINLINE_LITERNALS help optimize performance
and virtual memory usage for applications whose source code includes
literals. As the scalability and performance from reduced per-process
memory usage may or may not compensate for the incremental cost of
dynamically loading and unloading the data structures, and as the
performance of routines vs. inline code can be affected by the
availability of routines in cache, FIS suggests benchmarking to determine
the combination of qualifiers best suited to each workload. Note that
applications can freely mix routines compiled with different combinations
of qualifiers.
4 [no]o[bject][=filename]
[no]o[bject][=filename]
Instructs the compiler to produce an output object file and optionally
specifies a name for the object file using the optional filename argument.
When you do not specify a file name, the compiler produces an object file
with the same file name as the source file and an .o file extension.
When forming routine names, the compiler truncates object filenames to a
maximum length of 31 characters. For example, for a source file called
Adatabaseenginewithscalabilityproven.m the compiler generates an object
file called Adatabaseenginewithscalabilityp.o. Ensure that first 31
characters of source file names are unique.
The -noobject qualifier suppresses the production of an object file and is
usually used with the -list qualifier to produce only a listing file.
By default, the compiler produces object modules.
4 r[un]
r[un]
Invokes GT.M in Autostart Mode.
The next argument is taken to be an M entryref. That routine is
immediately executed, bypassing Direct Mode. Depending on the shell, you
may need to put the entryref in quotation marks (""). This qualifier does
not invoke the M compiler and is not compatible with any other qualifier.
4 s[pace]=lines
s[pace]=lines
Controls the spacing of the output in the listing file. -space=n specifies
n-1 blank lines separating every source line in the listing file. If n<1,
the M command uses single spacing in the listing.
If this qualifier appears without the -list qualifier, the M compiler
ignores the -space qualifier.
By default, listings use single spaced output (-space=1).
2 Execute_Source_Program
Execute Source Program
M source programs can be executed either from the shell or from GT.M
(Direct Mode).
3 Execute_in_Direct_Mode
Execute in Direct Mode
As discussed in the section on compiling source programs, the GT.M command
ZLINK compiles the source code into an object module and adds the object
module to the current image.
The run-time system also invokes auto-ZLINKing when an M command, in a
program or in Direct Mode, refers to a routine that is not part of the
current image.
M commands and functions that may initiate auto-ZLINKing are:
* DO
* GOTO
* ZBREAK
* ZGOTO
* ZPRINT
* $TEXT()
GT.M auto-ZLINKs the routine only under these conditions:
$ZROUTINES is a read-write special variable that contains a directory
search path used by ZLINK and auto-ZLINK to locate source and object
files.
When the argument to a ZLINK command includes a pathname, $ZSOURCE
maintains that pathname as a default for ZEDIT and ZLINK. $ZSOURCE is a
read-write special variable.
Once you use the ZEDIT or ZLINK commands, $ZSOURCE can contain a partial
file specification. The partial file specification can be a directory path
(full or relative), a file name, and a file extension. You can set
$ZSOURCE with an M SET command. A ZLINK without an argument is equivalent
to ZLINK $ZSOURCE.
For additional information on $ZSOURCE and $ZROUTINES, refer to Chapter 8:
"ISV".
Example:
GTM>ZLINK "taxes"
If ZLINK finds taxes.m or taxes.o, the command adds the routine taxes to
the current image. When ZLINK cannot locate taxes.o, or when it finds
taxes.o is older than taxes.m, it compiles taxes.m, producing a new
taxes.o. Then, it adds the contents of the new object file to the image.
3 Locate_Source_Directory
Locate Source Directory
A ZLINK command that does not specify a directory uses $ZROUTINES to
locate files. When $ZROUTINES is null, ZLINK uses the current directory.
$ZROUTINES is initialized to the value of the gtmroutines environment
variable.
When the file being linked includes an explicit directory, ZLINK and
auto-ZLINK searches only that directory for both the object and the source
files. If compilation is required, ZLINK places the new object file in the
named directory.
A subsequent ZLINK searching for this object file will never find the
object file in the specified directory unless the directory is added to
the search path in $ZROUTINES, or the object file is moved to another
directory already in the search path.
ZLINK cannot change a currently active routine, (e.g., a routine displayed
in a ZSHOW "S" of the stack). ZLINK a currently active routine by first
removing it from the M stack, using ZGOTO, or one or more QUITs.
To maintain compatibility with other editions of GT.M that do not permit
the percent sign (%) in a file name, GT.M uses an underscore (_) in place
of the percent in the file name.
Example:
GTM>zlink "_MGR"
This ZLINK links the M routine %MGR into the current image.
2 Execute_from_Shell
Execute from Shell
You can run a program from the shell prompt using the following command:
$ mumps -run ^filename
The mumps command searches the directories specified by the environment
variable gtmroutines to locate the specified file name.
Example:
$ mumps -run ^payroll
This executes a routine named payroll.
2 Processing_Errors
Processing Errors
+------------------------------------------------------------------------+
| | Executing in Direct | Executing from the Shell (mumps -run |
| | Mode | ^routine) |
|---------+-----------------------+--------------------------------------|
| | Suitable for | |
| Usage | development and | Suitable for production. |
| | debugging. | |
|---------+-----------------------+--------------------------------------|
| | Not invoked for code | Errors are suppressed and cause a |
| | entered at the direct | silent process exit. Set the |
| | mode prompt; Note | environment variable gtm_etrap which |
| | that XECUTE code is | overrides the default $ZTRAP="B". |
| | treated as not | |
| Error | entered at the direct | If needed, error handlers can |
| Handler | mode prompt | include appropriate error |
| | | notification to $PRINCIPAL. For |
| | The default | example, the gtmprofile script sets |
| | $ZTRAP="B" brings a | a default $ETRAP value of |
| | process to the Direct | "Write:(0=$STACK) ""Error occurred: |
| | Mode for debugging. | "",$ZStatus,!" which you can |
| | | customize to suit your needs. |
|---------+--------------------------------------------------------------|
| | GT.M processes send error messages to stderr only under the |
| | following conditions: |
| | |
| | * The error is fatal which means that the process is about |
| stderr | to terminate |
| | * During compilation except of indirection or XECUTE |
| | * The process is about to enter direct mode due to a BREAK |
| | command |
| | * The erroneous code was entered at the direct mode prompt |
+------------------------------------------------------------------------+
1 Opr_Dbg_Dir_Mode
Opr Dbg Dir Mode
Direct Mode is an important tool in GT.M because it allows you to
interactively debug, modify, and execute M routines. Direct Mode is a
shell that immediately compiles and executes GT.M commands providing an
interpretive-like interface. M simplifies debugging by using the same
commands for debugging that are used for programming.
2 Operate_Direct_Mode
Operate Direct Mode
This section provides an overview of the following basic operational
issues in Direct Mode:
* Entering Direct Mode
* Available functionality
* Exiting Direct Mode
3 Entering_Direct_Mode
Entering Direct Mode
To enter Direct Mode, type $gtm_dist/mumps -direct at the shell prompt.
$ $gtm_dist/mumps -direct
GTM>
This shows using $gtm_dist/mumps -direct at the prompt to enter Direct
Mode.
To create a gtm alias in your shell startup file (in the example below the
startup file is assumed to be a .profile file):
1. Open an edition session for your .profile file by typing:
$vi .profile
2. Add a function to the file to define your gtm alias:
gtm(){ $gtm_dist/mumps -direct}
3. save the file.
Now, when you want to enter Direct Mode for an editing or debugging
session, simply type gtm at the shell prompt.
Example:
$ gtm
GTM>
This shows that the gtm alias typed at the shell prompt also takes you to
the Direct Mode.
3 Functionality_Available_in_Direct_Mode
Functionality Available in Direct Mode
This section provides an overview of basic functionality and concepts that
enhance your use of Direct Mode.
4 Command_Recall
Command Recall
Direct Mode includes a line command recall function to display previously
entered command lines. Use <CTRL-B> or the Up Arrow key at the GTM> prompt
to scroll back through command lines. Use the Down Arrow key to scroll
forward through the command lines. GT.M displays one command line at a
time.You may delete and reenter characters starting at the end of a
recalled line.
The RECALL command is another way to access previously entered Direct Mode
command lines. RECALL is only valid in Direct Mode and causes an error if
it appears in other M code.
The format of the RECALL command is:
REC[ALL] [intlit|strlit]
If the Direct Mode session has just started, you may not have entered 99
lines for GT.M to save and therefore you will not have 99 lines to look
at. The most recently entered GT.M command line has the number one (1),
older lines have higher numbers. GT.M does not include the RECALL command
in the listing. If the RECALL command is issued from a location other than
the Direct Mode prompt, GT.M issues a run-time error.
Example:
GTM>write $zgbldir
/usr/lib/fis-gtm/V5.4-002B_x86/mumps.gld
GTM>set $zgbldir="test.gld"
GTM>set a=10
GTM>set b=a
GTM>recall
1 set b=a
2 set a=10
3 set $zgbldir="test.gld"
4 write $zgbldir
GTM>
This REC[ALL] command displays the previously entered commands.
You can also display a selected command by entering RECALL and the line
number of the command you want to retrieve.
Example:
GTM>recall 2
GTM>set a=10
This RECALLs the line number two (2).
If the RE[CALL] command includes a text parameter, GT.M displays the most
recent command matching the text after the RE[CALL] command.
Example:
GTM>recall write
GTM>write $zgbldir
This RECALLs "WRITE", the command most recently beginning with this text.
Note that the RECALL command text is case sensitive. The RECALL command
with a text argument treats WRITE and write differently, that is, it
treats them case sensitively. If you first type the WRITE command in
lower-case and then type WRITE in upper-case to recall it, the RECALL
command does not find a match.
4 Line_Editing
Line Editing
GT.M permits the use of the GT.M command line editor at the Direct Mode
prompt and during M READs from a terminal. The GT.M line editor allows
cursor positioning using the <CTRL> key, edit keypad and function keys.
The GT.M Direct Mode line editing keys are as follows:
Backspace: Deletes the character to the left of the cursor
Delete: Deletes the character under the cursor
Up-arrow: Moves to a less recent item in the RECALL list
Down-arrow: Moves to a more recent item in the RECALL list
Left-arrow: Moves the cursor one character to the left
Right-arrow: Moves the cursor one character to the right
<CTRL-A>: Moves the cursor to the beginning of the line
<CTRL-B>: Moves the cursor one character towards the beginning of the line
<CTRL-D>: On an empty line, terminates GT.M and returns control to the
shell.
<CTRL-E>: Moves the cursor to the end of the line
<CTRL-F>: Moves the cursor one character towards the end of the line
<CTRL-K>: Deletes all characters from the cursor to the end of the line
<CTRL-U>: Deletes the entire line
**Note**
When entering commands at the direct mode prompt, the insert mode can be
toggled for that line by using the insert key. When GT.M starts, insert
mode is enabled unless the value of the gtm_principal_editing environment
variable includes the string NOINSERT. If insert mode is disabled or
enabled for the $PRINCIPAL device by an USE statement before returning to
direct mode, it will remain disabled or enabled at direct mode. The insert
mode can be toggled within a direct mode line using the terminal's INSERT
key.
**Important**
GT.M deletes the character under the cursor when you press the key on the
keyboard that sends the escape sequence which maps to the kdch1 capability
in your current terminfo entry (by convention, the Delete key). If the
current terminfo entry is missing the kdch1 capability, GT.M uses a
default value derived from members of the DEC VT terminal family, as it
does for selected other missing terminfo capabilities. In prior version,
in response to the escape sequence defined by kdch1, GT.M deleted the
character immediately on the left, akin to the Backspace key and assumed
an inappropriate value if a definition for kdch1 was missing. If you wish
to retain the prior behavior, the simplest way is to configure your
terminal emulator to send the same character sequences for the Delete key
that it does for the Backspace key. You can alternatively modify your
terminfo setting: for example, create an editable version of your terminfo
entry in a temporary file with a command such as: infocmp > /tmp/$$_$TERM
and edit the temporary file to replace the entry for the kbs capability
with the one in the kdch1 capability. Save your changes, and compile the
edited file into a usable terminfo entry, for example:
export TERMINFO=$HOME/.terminfo # You may need to add this to your login profile
profilemkdir -p $TERMINFO
tic /tmp/$$_$TERM # or whatever your temporary file name was
When modifying terminfo capabilities, always look for unintended changes
in the behavior of other applications, for example, text editors, that
also rely on those capabilities. In the worst case, you may need to toggle
between alternate terminfo entries for GT.M and other applications while
you evaluate different options. Also, for terminfo entries without the
cud1 capability, GT.M uses a linefeed when moving to the next line in
direct mode.
4 The_M_Invocation_Stack
The M Invocation Stack
The ANSI M Standard describes certain M operations in terms of how a
stack-based virtual machine would operate. A stack is a repository for
tracking temporary information on a "last-in/first-out" (LIFO) basis. M
program behavior can be understood using a stack-based model. However, the
standard is not explicit in defining how an implementation must maintain a
stack or even whether it must use one at all.
The stack model provides a trail of routines currently in progress that
shows the location of all the M operations that performed the invocations
leading to the current point.
The ZSHOW command makes this stack information available within GT.M.
3 Exiting_Direct_Mode
Exiting Direct Mode
Five M commands can terminate a Direct Mode session:
* HALT
* ZHALT
* ZCONTINUE
* GOTO
* ZGOTO
The HALT command exits Direct Mode and terminates the M process.
The ZHALT command exits Direct Mode and returns the exit status to the
calling environment.
The ZCONTINUE command instructs GT.M to exit Direct Mode and resume
routine execution at the current point in the M invocation stack. This may
be the point where GT.M interrupted execution and entered Direct Mode.
However, when the Direct Mode interaction includes a QUIT command, it
modifies the invocation stack and causes ZCONTINUE to resume execution at
another point.
The GOTO and ZGOTO commands instruct GT.M to leave Direct Mode, and
transfer control to a specified entry reference.
1 M_Lang_Features
M Lang Features
MUMPS is a general purpose language with an embedded database system. This
section describes the features of the language that are not covered as
Commands, Functions, or Intrinsic Special Variables chapters.
2 Data_Types
Data Types
M operates with a single basic data type, string. However, M evaluates
data using methods that vary according to context.
3 Numeric_Expressions
Numeric Expressions
When M syntax specifies a numexpr, M evaluates the data as a sequence of
ASCII characters that specify a number. M stops the evaluation and
provides the result generated from successfully evaluated characters when
it encounters any character that is not the following:
* A digit 0-9
* A plus sign (+) or minus sign (-) and also the first character in the
string
* The first decimal point (.) in the string
3 Numeric_Accuracy
Numeric Accuracy
GT.M provides 18 digits of accuracy, independent of the decimal point (.)
placement, and a numeric range from 10**(-43) to (10**47). Numbers with
three digits or fewer to the right of the decimal point are precise.
3 Integer_Expressions
Integer Expressions
When M syntax specifies an intexpr, M evaluates the data as it would a
numexpr except that it stops the evaluation at any decimal point including
the first.
3 Truth-valued_Expressions
Truth-valued Expressions
When M syntax specifies a tvexpr, M evaluates the data as a numeric.
However, it stops the evaluation and returns a true value (1) as soon as
it encounters a non-zero digit, otherwise it returns a false value (0). In
other words, M treats expressions that have a non-zero numeric value as
true, and expressions that have a zero numeric value as false. The sign
and/or decimal have no affect on the evaluation of a truth-valued
expression.
2 M_Names
M Names
M uses names for variables, LOCK command arguments, labels on lines, and
routine names. M names are alphanumeric and must start with an alphabetic
character or a percent sign (%).
The percent sign can only appear as the first character in a name. By
convention, names starting with percent signs are generally
application-independent or distinguished in some similar way.
M does not reserve any names. That is, M always distinguishes keywords by
context. Therefore, M permits a variable or a label called SET even though
the language has a command called SET.
M names are case sensitive. That is, M treats ABC, Abc, ABc, AbC ABC, and
abc as six different names.
M does not restrict the length of names in the main body of the standard.
However, the portability section of the standard recommends limiting names
to a maximum of eight (8) characters. GT.M's limit of 31 characters
applies to:
* Local variables names
* Global variables names
* Routine names
* Source and object file names (not including the extension)
* Label names
* Local lock resource names
* Global lock resource names
A trigger name is up to 28 characters and a replication instance name is
up to 15 characters.
2 Variables
Variables
M does not require predefinition of variable type or size. M variables are
either local or global. Any variable may be unsubscripted or subscripted.
3 Arrays_and_Subscripts
Arrays and Subscripts
In M, subscripted variables identify elements in sparse arrays. Sparse
arrays comprise existing subscripts and data nodes -; no space is reserved
for potential data nodes. These arrays generally serve logical, rather
than mathematical, purposes.
M array subscripts are expressions, and are not restricted to numeric
values.
The format for an M global or local variable is:
[^]name[(expr1[,...])]
The body of the M standard places no restrictions on variable names.
However, the portability section of the standard does suggest limits on
the length of an individual subscript expression, and on the total length
of a variable name. The measurement for the length of names includes the
length of the global variable name itself, the sum of the lengths of all
the evaluated subscripts, and an allowance for an overhead of two (2)
times the number of subscripts. The total must not exceed 237. For
globals, GT.M permits this total to be modified with GDE up to 255. For
locals, GT.M limits the length of individual subscripts to the maximum
string length of 32,767. GT.M restricts the number of subscripts for local
or global variables to 31.
3 M_Collation_Sequences
M Collation Sequences
M collates all canonic numeric subscripts ahead of all string subscripts,
including strings such as those with leading zeros that represent
non-canonic numbers. Numeric subscripts collate from negative to positive
in value order. String subscripts collate in ASCII sequence. In addition,
GT.M allows the empty string subscript in most contexts, (the null, or
empty, string collates ahead of all canonic numeric subscripts).
GT.M allows definition of alternative collation sequences. For complete
information on enabling this functionality, refer to the
"Internationalization" chapter in the GT.M Programmer's Guide.
3 Local_Variables
Local Variables
A local variable in M refers to a variable used solely within the scope of
a single process. Local variable names have no leading delimiter.
M makes a local variable available and subject to modification by all
routines executed within a process from the time that variable is first
SET until it is KILLed, or until the process stops executing M. However, M
"protects" a local variable after that variable appears as an argument to
a NEW command, or after it appears as an element in a formalist used in
parameter passing. When M protects a local variable, it saves a copy of
the variable's value and makes that variable undefined. M restores the
variable to its saved value during execution of the QUIT that terminates
the process stack level associated with the "protecting" NEW or formalist.
For more information on NEW and QUIT, refer to the "Commands" chapter in
the GT.M Programmer's Guide.
M restricts the following uses of variables to local variables:
* FOR command control variables.
* Elements within the parentheses of an "exclusive" KILL.
* TSTART [with local variables list].
* A KILL with no arguments removes all current local variables.
* NEW command arguments.
* Actualnames used by pass-by-reference parameter passing.
3 GV_and_Resource_Name_Env
GV and Resource Name Env
M recognizes an optional environment specification in global names or in
the LOCK resource names (nrefs), which have analogous syntax. Global
variable names have a leading caret symbol (^) as a delimiter.
M makes a global variable available, and subject to modification by all
routines executed within all processes in an environment, from the time
that variable is first SET until it is KILLed.
3 Naked_References
Naked References
M accepts an abbreviation of the global name under some circumstances.
When the leading caret symbol (^) immediately precedes the left
parenthesis delimiting subscripts, the global variable reference is called
a naked reference. M evaluates a naked reference by prefixing the last
used global variable name, except for its last subscript, to the list of
subscripts specified by the naked reference. The prefixed portion is known
as the naked indicator. An attempt to use a naked reference when the prior
global reference does not exist, or did not contain a subscript, generates
an error.
Because M has only one process-wide naked indicator which it maintains as
a side affect of every evaluation of a global variable, using the naked
reference requires an understanding of M execution sequence. M execution
generally proceeds from left to right within a line, subject to commands
that change the flow of control. However, M evaluates the portion of a SET
command argument to the right side of the equal sign before the left side.
Also, M does not evaluate any further $SELECT() arguments within the
function after it encounters a true selection argument.
In general, using naked references only in very limited circumstances
prevents problems associated with the naked indicator.
3 Global_Variable_Name_Environments
Global Variable Name Environments
M recognizes an optional environment specification in global names. The
environment specification designates one of some set of alternative
database files.
The syntax for global variable names that include an environment
specification is:
^|expr|name[(subscript[,...])]
In GT.M, the expression identifies the Global Directory for mapping the
global variable.
Environment specifications permit easy access to global variables in
alternative databases, including other "copies" of active variables in the
current database. Environment specifications are sometimes referred to as
extended global syntax or extended value syntax.
GT.M also allows:
^|expr1,expr2|name[(subscript[,...])]
Where the first expression identifies the Global Directory and the second
expression is accepted but ignored by GT.M.
To improve compatibility with some other M implementations, GT.M also
accepts another non-standard syntax. In this syntax, the leading and
trailing up-bar (|) are respectively replaced by a left square-bracket ([)
and a right square-bracket (]). This syntax also requires expratoms,
rather than expressions.
The formats for this non-standard syntax are:
^[expratom1]name[(subscript...)]
or
^[expratom1,expratom2]name[(subscript...)]
Where expratom1 identifies the Global Directory and expratom2 is a dummy
variable. Note that the first set of brackets in each format is part of
the syntax. The second set of square brackets is part of the meta-language
identifying an optional element.
Example:
$ gtmgbldir=Test.GLD
$ export gtmgbldir
$ GTM
GTM>WRITE $ZGBLDIR
TEST.GLD
GTM>WRITE ^A
THIS IS ^A IN DATABASE RED
GTM>WRITE ^|"M1.GLD"|A
THIS IS ^A IN DATABASE WHITE
GTM>WRITE $ZGBLDIR
TEST.GLD
GTM>HALT
$ echo gtmgbldir
TEST.GLD
The statement WRITE ^|"M1.GLD"|A writes variable ^A using the Global
Directory, M1.GLD, but does not change the current Global Directory.
Example:
GTM>WRITE $ZGBLDIR
M1.GLD
GTM>WRITE ^A
THIS IS ^A IN DATABASE WHITE
GTM>WRITE ^|"M1.GLD"|A
THIS IS ^A IN DATABASE WHITE
The statement WRITE ^|"M1.GLD"|A is equivalent to WRITE ^A.
Specifying separate Global Directories does not always translate to using
separate databases.
Example:
GTM>WRITE ^|"M1.GLD"|A,!,^|"M2.GLD"|A,!,^|"M3.GLD"
|A,!
THIS IS ^A IN DATABASE WHITE
THIS IS ^A IN DATABASE BLUE
THIS IS ^A IN DATABASE WHITE
In this example, the WRITE does not display ^A from three GT.M database
files. Mapping specified by the Global Directory Editor (GDE) determines
the database file to which a Global Directory points.
This result could have occurred under the following mapping:
^|"M1.GLD"|A --> REGIONA --> SEGMENTA --> FILE1.DAT
^|"M2.GLD"|A --> REGIONA --> SEGMENT1 --> FILE2.DAT
^|"M3.GLD"|A --> REGION3 --> SEGMENT3 --> FILE1.DAT
For more information on Global Directories, refer to the "Global Directory
Editor" chapter of the GT.M Administration and Operations Guide.
2 Literals
Literals
M has both string and numeric literals.
3 String_Literals
String Literals
A string literal (strlit) is enclosed in quotation marks (" ") and can
contain a sequence of ASCII and Unicode characters. While the standard
indicates the characters must be graphic, GT.M accepts non-graphic
characters and, at compile-time, gives a warning. Using $CHAR() and
concatenate to represent non-graphic characters in strings not only avoids
the warning but is less error prone and makes for easier understanding. M
attempts to use character text that appears outside of quotation mark
delimiters according to context, which generally means as a local variable
name.
To include a quotation mark (") within a strlit, use a set of two
quotation marks ("" "").
Example:
GTM>write """"
"
GTM>
The WRITE displays a single quotation mark because the first quotation
mark delimits the beginning of the string literal, the next two quotation
marks denote a single quote within the string, and the last quotation mark
delimits the end of the string literal.
Use the $CHAR function and the concatenation operator to include control
characters within a string.
Example:
GTM>WRITE "A"_$CHAR(9)_"B"
A B
GTM>
The WRITE displays an "A," followed by a tab (<HT>), followed by a "B"
using $CHAR(), to introduce the non-graphic character.
3 Numeric_Literals
Numeric Literals
In M, numeric literals (numlit) are entered without surrounding
delimiters.
Example:
GTM>WRITE 1
1
GTM> WRITE 1.1
1.1
These display numeric literals that are integer and decimal.
M also accepts numeric literals in the form of a mantissa and an exponent,
separated by a delimiter of "E" in uppercase. The mantissa may be an
integer or a decimal fraction. The integer exponent may have an optional
leading minus sign (-).
Example:
GTM>WRITE 8E6
8000000
GTM> WRITE 8E-6
.000008
GTM>
**Caution**
The exponential numeric form may lead to ambiguities in the meaning of
subscripts. Because numeric subscripts collate ahead of string subscripts,
the string subscript "01E5" is not the same as the numeric subscript 01E5.
GT.M handles numeric strings which are not canonical within the
implementation as strings unless the application specifically requests
they be treated as numbers. Any use in a context defined as numeric
elicits numeric treatment; this includes operands of numeric operators,
numeric literals, and some intrinsic function arguments. When the code
creates a large number out of range , GT.M gives a NUMOFLOW error. When
the code creates a small fractional number out of range GT.M treats it as
zero (0). The GT.M number range is (to the limit of accuracy) 1E-43 to
1E47. When the application creates an in-range number that exceeds the
GT.M numeric accuracy of 18 significant digits, GT.M silently retains the
most significant digits. With standard collation, GT.M collates canonic
numeric strings used as subscripts numerically, while it collates
non-canonic numbers as strings.
2 Expressions
Expressions
The following items are legal M expression atoms (expratom). An expression
atom is a component of an M expression.
* Local variables
* Global variables
* Intrinsic special variables
* Intrinsic functions
* Extrinsic functions
* Extrinsic special variables
* Numeric literals
* String literals
* An expression enclosed in parentheses
* Any of the above preceded by a unary operator
In addition, any of these items may be combined with a binary operator and
another expression atom.
2 Operators
Operators
M has both unary and binary operators.
3 Precedence
Precedence
All unary operations have right to left precedence.
All M binary operations have strict left to right precedence. This
includes all arithmetic, string, and logical operations. Hierarchies of
operations require explicit establishment of precedence using parentheses
(). Although this rule is counterintuitive, it is easy to remember and has
no exceptions.
3 Arithmetic_Operators
Arithmetic Operators
All arithmetic operators force M to evaluate the expressions to which they
apply as numeric. The arithmetic operators are:
+ as a unary operator simply forces M to evaluate the expression following
as numeric; as a binary operator it causes M to perform addition.
- as a unary operator causes M to negate the expression following; as a
binary operator it causes M to perform subtraction.
* binary operator for multiplication.
** binary operator for exponentiation.
/ binary operator for fractional division.
\ binary operator for integer division.
# binary operator for modulo, that is, causes M to produce the remainder
from integer division of the first argument by the second.
Remember that precedence is left to right for all arithmetic operators.
Example:
GTM>WRITE 1+1
2
GTM>WRITE 2-1
1
GTM>WRITE 2*2
4
GTM>WRITE 3**2
9
GTM>WRITE 4/2
2
GTM>WRITE 7
2
GTM>WRITE 7#3
1
GTM>
This simple example demonstrates how each arithmetic binary operation uses
numeric literals.
Example:
GTM>WRITE +"12ABC"
12
GTM>WRITE --"-3-4"
-3
GTM>
The first WRITE shows the unary plus sign (+) operation forcing the
numeric evaluation of a string literal. The second WRITE demonstrates the
unary minus sign (-). Note the second minus sign within the string literal
does not cause subtraction, but rather, terminates the numeric evaluation
with the result of negative three (-3). Each of the leading minus signs
causes one negation and therefore, the result is negative three (-3).
3 Logical_Operators
Logical Operators
M logical operators always produce a result that is TRUE (1) or FALSE (0).
All logical operators force M to evaluate the expressions to which they
apply as truth-valued. The logical operators are:
' unary NOT operator negates current truth-value; M accepts placement of
the NOT operator next to a relational operator, for example, A'=B as
meaning '(A=B).
&binary AND operator produces a true result only if both of the
expressions are true.
! binary OR operator produces a true result if either of the expressions
is true.
Remember that precedence is always left to right, and that logical
operators have the same precedence as all other operators.
Example:
GTM>WRITE '0
1
GTM>WRITE '1
0
GTM>WRITE '5689
0
GTM>WRITE '-1
0
GTM>WRITE '"ABC"
1
GTM>
The above example demonstrates the unary NOT operation. Note that any
non-zero numeric value is true and has a false negation.
Example:
GTM>WRITE 0&0
0
GTM>WRITE 1&0
0
GTM>WRITE 0&1
0
GTM>WRITE 1&1
1
GTM>WRITE 2&1
1
GTM>WRITE 0!0
0
GTM>WRITE 1!0
1
GTM>WRITE 0!1
1
GTM>WRITE 1!1
1
GTM>WRITE 2!1
1
GTM>
The above example demonstrates all cases covered by the binary logical
operators.
3 String_Operators
String Operators
All string operators force M to evaluate the expressions to which they
apply as strings. The string operator is:
_binary operator causes M to concatenate the second expression with the
first expresion
Example:
GTM>WRITE "B"_"A"
BA
GTM>WRITE "A"_1
A1
GTM>
The above example demonstrates M concatenation.
3 Numeric_Relational_Operators
Numeric Relational Operators
M relational operators always generate a result of TRUE (1) or FALSE (0).
All numeric relational operators force M to evaluate the expressions to
which they apply as numeric. The numeric relational operators are:
>binary arithmetic greater than
<binary arithmetic less than
The equal sign (=) does not force numeric evaluation, and should be viewed
as a string operator. However, the equal sign between two numeric values
tests for numeric equality.
Other numeric relations are formed using the logical NOT operator
apostrophe (') as follows:
'> not greater than, that is, less than or equal to
'< not less than, that is, greater than or equal to
>= greater than or equal to, that is, not less than
<= less than or equal to, that is, not greater than
'= not equal, numeric or string operation
Example:
GTM>WRITE 1>2
0
GTM>WRITE 1<2
1
GTM>
The above example demonstrates the basic arithmetic relational operations.
Example:
GTM>WRITE 1'<2
0
GTM>WRITE 2'<1
1
GTM>
The above example demonstrates combinations of arithmetic, relational
operators with the logical NOT operator.
3 String_Relational_Operators
String Relational Operators
M relational operators always generate a result of TRUE (1) or FALSE (0).
All string relational operators force M to evaluate the expressions to
which they apply as strings. The string relational operators are:
= binary operator causes M to produce a TRUE if the expressions are equal.
[ binary operator causes M to produce a TRUE if the first expression
contains the ordered sequence of characters in the second expression.
] binary operator causes M to produce a TRUE if the first expression
lexically follows the second expression in the character encoding
sequence, which by default is ASCII.
]] binary operator causes M to produce a TRUE if the first expression
lexically sorts after the second expression in the subscript collation
sequence.
Note that all non-empty strings lexically follow the empty string, and
every string contains the empty string.
Other string relations are formed using the logical NOT operator
apostrophe (') as follows:
'[ does not contain.
'] does not follow, that is, lexically less than or equal to.
']] does not sort after, that is, lexically less than or equal to in the
subscript collation sequence.
'= not equal, numeric or string operation.
Example:
GTM>WRITE "A"="B"
0
GTM>WRITE "C"="C"
1
GTM>WRITE "A"["B"
0
GTM>WRITE "ABC"["C"
1
GTM>WRITE "A"]"B"
0
GTM>WRITE "B"]"A"
1
GTM>WRITE "A"]]"B"
0
GTM>WRITE "B"]]"A"
1
These examples demonstrate the string relational operators using string
literals.
Example:
GTM>WRITE 2]10
1
GTM>WRITE 2]]10
0
GTM>WRITE 0]"$"
1
GTM>WRITE 0]]"$"
0
These examples illustrate that when using the primary ASCII character set,
the main difference in the "follows" (]) operator and the "sorts-after"
(]]) operator is the way they treat numbers.
Example:
GTM>WRITE 1=1
1
GTM>WRITE 1=2
0
GTM>WRITE 1="1"
1
GTM>WRITE 1=01
1
GTM>WRITE 1="01"
0
GTM>WRITE 1=+"01"
1
GTM>
These examples illustrate the dual nature of the equal sign operator. If
both expressions are string or numeric, the results are straight forward.
However, when the expressions are mixed, the native string data type
prevails.
Example:
GTM>WRITE "a"'="A"
1
GTM>WRITE "FRED"'["RED"
0
GTM>WRITE "ABC"']""
0
These examples demonstrate combinations of the string relational operators
with the NOT operator.
3 Pattern_Match_Operator
Pattern Match Operator
The pattern match operator (?) causes M to return a TRUE if the expression
ahead of the operator matches the characteristics described by the pattern
following the operator. The pattern is not an expression.
Patterns are made up of two elements:
1. A repetition count
2. A pattern code, a string literal or an alternation list
The element following the pattern match operator may consist of an
indirection operator, followed by an element that evaluates to a
legitimate pattern.
The repetition count consists of either a single integer literal or a
period (.) delimiter with optional leading and trailing integer literals.
A single integer literal specifies an exact repetition count. The period
syntax specifies a range of repetitions where the leading number is a
minimum and the trailing number is a maximum. When the repetition count is
missing the leading number, M assumes there is no minimum, (i.e., a
minimum of zero). When the repetition count is missing the trailing
number, M does not place a maximum on the number of repetitions.
The pattern codes are:
A alphabetic characters upper or lower case
C control characters ASCII 0-31 and 127
E any character; used to pass all characters in portions of the string
where the pattern is not restricted
L lower-case alphabetic characters, ASCII 97-122
N digits 0-9, ASCII 48-57
P punctuation, ASCII 32-47, 58-64, 91-96, 123-126
U upper-case alphabetic characters, ASCII 65-90
Pattern codes may be upper or lower case and may be replaced with a string
literal. GT.M allows the M pattern match definition of patcodes A, C, N,
U, L, and P to be extended or changed, (A can only be modified implicitly
by modifying L or U) and new patcodes added. For detailed information on
enabling this functionality, refer to the "Internationalization" chapter
in the GT.M Programmer's Guide.
**Note**
The GT.M compiler accepts pattern codes other than those explicitly
defined above. If, at run-time, the pattern codes come into use and no
pattern definitions are available, GT.M issues a run-time error
(PATNOTFOUND). GT.M does not currently implement a mechanism for Y and Z
patterns and continues to treat those as compile-time syntax errors.
Example:
GTM>WRITE "ABC"?3U
1
GTM>WRITE "123-45-6789"?3N1"-"2N1"-"4N
1
The first WRITE has a simple one-element pattern while the second has
multiple elements including both codes and string literals. All the
repetition counts are fixed.
Example:
I x?.E1C.E W !,"Must not contain a control character" Q
This example uses a pattern match to test for control characters.
Example:
I acn?1U.20A1","1U.10A D
.S acn=$G((^ACX($P(acn,","),$P(acn,",",2)))
This example uses a pattern match with implicit minimums to determine that
an "account number" is actually a name, and to trigger a look-up of the
corresponding account number in the ^ACX cross index.
The pattern match operator accepts the alteration syntax. Alteration
consists of a repeat count followed by a comma-delimited list of patatoms
enclosed in parentheses "()". The semantic is that the pattern matches if
any of the listed patterns matches the operand string. For example,
?1(2N1"-"7N,3N1"-"2N1"-"4N).1U might be a way to match either a social
security number or a taxpayer ID. Since alternation is defined as one of
the ways of constructing a patatom, alternation can nest (be used
recursively).
**Note**
Complex pattern matches may not be efficient to evaluate, so every effort
should be made to simplify any commonly used pattern and to determine if
more efficient alternative logic would be more appropriate.
2 Commands
Commands
M commands may be abbreviated to a defined prefix. Most commands have
arguments. However, some commands have either optional arguments or no
arguments. When a command has no argument and is followed by more commands
on the same line, at least two spaces (<SP>) must follow the command
without arguments. Commands that accept arguments generally accept
multiple arguments on the same command. M treats multiple arguments the
same as multiple occurrences of the same command, each with its own
argument.
3 Postconditionals
Postconditionals
M provides postconditionals as a tool for placing a condition on the
execution of a single command and, in some cases, a single command
argument. A postconditional consists of a colon (:) delimiter followed by
a truth-valued expression. When the expression evaluates to true, M
executes the command occurrence. When the expression evaluates to false, M
does not execute the command occurrence.
4 Command_Postconditionals
Command Postconditionals
Command postconditionals appear immediately following a command and apply
to all arguments for the command when it has multiple arguments. All
commands except commands that themselves have a conditional aspect accept
a command postconditional. Among the M standard commands, ELSE, FOR, and
IF do not accept command postconditionals. All the GT.M command extensions
accept command postconditionals.
4 Argument_Postconditionals
Argument Postconditionals
Commands that affect the flow of control may accept postconditionals on
individual command arguments. Because multiple arguments act as multiple
commands, this is a straight-forward application of the same principal as
command postconditional. The only M standard commands that accept argument
postconditionals are DO, GOTO, and XECUTE. The GT.M command extensions
that accept argument postconditionals are BREAK, ZGOTO, and ZSYSTEM.
3 Timeouts
Timeouts
M provides timeouts as a tool to retain program control over commands of
indefinite duration. A timeout consists of a colon (:) delimiter on an
argument, followed by a numeric expression specifying the number of
seconds for M to attempt to execute the command. When the timeout is zero
(0), M makes a single attempt to complete the command.
GT.M has been designed to allow large timeout values, and to protect
against arithmetic overflow when converting large timeout values to
internal representations. When a command has a timeout, M maintains the
$TEST intrinsic special variable as the command completes. If the command
completes successfully, M sets $TEST to TRUE (1). If the command times out
before successful completion, M sets $TEST to FALSE (0). When a command
argument does not specify a timeout, M does not maintain $TEST.
When a READ times out, M returns any characters that have arrived between
the start of the command and the timeout. M does not produce any partial
results for any of the other timed commands.
2 M_Locks
M Locks
The LOCK command reserves one or more resource names. Only one process at
a time can reserve a resource name. Resource names follow exactly the same
formation rules as M variables. They may be unsubscripted or subscripted
and may or may not have a leading caret (^) prefix. M code commonly uses
LOCKs as flags that control access to global data. Generally, a LOCK
specifies the resource with the same name as the global variable that
requires protected access. However, this is only a convention. LOCKing
does not keep two or more processes from modifying the same global
variable. It only keeps another process from LOCKing the same resource
name at the same time.
M LOCKs are hierarchical. If one process holds a LOCK on a resource, no
other process can LOCK either an ancestor or a descendant resource. For
example, a LOCK on ^A(1,2) blocks LOCKs on either ^A(1), or ^A(1,2,3), but
not on, for example, ^A(2) or its descendants.
A LOCK argument may contain any subscripted or unsubscripted M variable
name including a name without a preceding caret symbol (^). As they have
the appearance of local variable names, resource names with no preceding
caret symbol (^) are commonly referred to as "local LOCKs" even though
these LOCKs interact with other processes.
2 Intrinsic_Functions
Intrinsic Functions
M Intrinsic Functions start with a single dollar sign ($) and have one or
more arguments enclosed in parentheses () and separated by commas (,).
These functions provide an expression result by performing actions that
would be impossible or difficult to perform using M commands. It is now
possible to invoke a C function in a package via the external call
mechanism.
2 Intrinsic_Special_Variables
Intrinsic Special Variables
M Intrinsic Special Variables start with a single dollar sign ($). GT.M
provides such variables for program examination. In some cases, the
Intrinsic Special Variables may be SET to modify the corresponding part of
the environment.
2 Routines
Routines
M routines have a name and consist of lines of code followed by a
formfeed. M separates the name of a routine from the body of the routine
with an end-of-line which is a line-feed. This form is mostly used for
interchange with other M implementations and can be read and written by
the %RI and %RO utility routines.
GT.M stores routine sources in UNIX text files.
In M, a routine has no particular impact on variable management and may
include code that is invoked at different times and has no logical
intersection.
3 Lines
Lines
A line of M code consists of the following elements in the following
order:
* An optional label.
* A line-start delimiter. The standard defines the line-start delimiter
as a space (<SP>) character. In order to enhance routine readability,
GT.M extends M by accepting one or more tab (<HT>) characters as
line-start delimiters.
* Zero or more level indicators, which are periods (.). The level
indicators show the level of nesting for argumentless DO commands: the
more periods, the deeper the nesting. M ignores lines that contain
level indicators unless they directly follow an argumentless DO
command with a matching level of nesting.
* Zero or more commands and their arguments. M accepts multiple commands
on a line. The argument(s) of one command are separated from the next
command by a command-start delimiter, consisting of one or more spaces
(<SP>).
* A terminating end-of-line, which is a line feed.
4 Labels
Labels
In addition to labels that follow the rules for M names, M accepts labels
consisting only of digits. In a label consisting only of digits, leading
zeros are considered significant. For example, labels 1 and 01 are
different. Formalists may immediately follow a label. A Formalists
consists of one or more names enclosed in parentheses (). Formalists
identify local variables that "receive" passed values in M parameter
passing. For more information, see "Parameter Passing".
In GT.M, a colon (:) delimiter may be appended to the label, which causes
the label to be treated as "local." Within the routine in which they
appear, they perform exactly as they would without the trailing colon but
they are inaccessible to other routines. Using local labels reduces object
size and linking overhead, for both ZLINK and host linking.
4 Comments
Comments
In addition to commands, a line may also contain a comment that starts
with a leading semi-colon (;) delimiter. The scope of a comment is the
remainder of the line. In other words, M ignores anything to the right of
the comment delimiter. The standard defines the comment delimiter (;) as
it would a command, and therefore requires that it always appear after a
linestart. GT.M extends the standard to permit comments to start at the
first character of a line or in an argument position.
3 Entry_References
Entry References
M entryrefs provide a generalized target for referring to a line within a
routine. An entryref may contain some combination of a label, an offset,
and a routine name (in that order). The offset is delimited by a plus sign
(+) and the routinename is delimited by a caret symbol(^). When an
entryref does not contain a label, M assumes the offset is from the
beginning of the routine. When an entryref does not contain an offset, M
uses an offset of zero (0). When an entryref does not contain a routine
name, M assumes the routine that is currently executing.
M permits every element in an entryref to have the form of an indirection
operator, followed by an element that evaluates to a legitimate occurrence
of that portion of the entryref.
**Note**
While most commands and functions that use entryrefs permit argument
indirection, M does not accept indirection that resolves to a combination
of label and offset or offset and routine name.
Offsets provide an extremely useful tool for debugging. However, avoid
their use in production code because they generally produce maintenance
problems.
3 Label_References
Label References
M labelrefs are a subset of entryrefs that exclude offsets and separate
indirection. Labelrefs are used with parameter passing.
2 Indirection
Indirection
M provides indirection as a means to defer definition of elements of the
code until run-time. Indirection names a variable that holds or "points"
to the element. The indirection operator is the "at" symbol (@).
3 Argument_Indirection
Argument Indirection
Most commands accept indirection of their entire argument.
Example:
GTM>set x="^INDER"
GTM>do @x
This example is equivalent to do ^INDER.
3 Atomic_Indirection
Atomic Indirection
Any expratom or any local or global variable name may be replaced by
indirection.
Example:
GTM>set x="HOOP",b="x"
GTM>write a="HULA "__@b
HULA HOOP
GTM>
This example uses indirection within a concatenation operation.
3 Entryref_Indirection
Entryref Indirection
Any element of an entryref may be replaced by indirection.
Example:
GTM>set lab="START",routine="PROG"
GTM>do @lab^@routine
This example is equivalent to do START^PROG.
3 Pattern_Code_Indirection
Pattern Code Indirection
A pattern code may be replaced by indirection.
Example:
GTM>FOR p="1U.20A1"",""1U.20A",5N IF x?@p QUIT
GTM>ELSE WRITE !,"Incorrect format" QUIT
This example uses pattern code indirection to test x for either a name or
a number.
3 Name_Indirection
Name Indirection
Indirection may replace the prefix of a subscripted global or local
variable name. This "name" indirection requires two indirection operators,
a leading operator similar to the other forms of indirection, and a
trailing operator marking the transition to those subscripts that are not
specified by indirection.
Example:
GTM>SET from="B",to="^A(15),x=""
GTM>FOR SET x=$O(@from@(x)) Q:x="" S @to@(x)=@from@(x)
This example uses name indirection to copy the level contents of a local
array to a part of a global array. The example assumes that all existing
first level nodes of variable B have data.
3 Indirection_Concerns
Indirection Concerns
M indirection provides a very powerful tool for allowing program
abstraction. However, because indirection is frequently unnecessary and
has some disadvantages, use it carefully.
Because routines that use indirection in some ways do not contain adequate
information for easy reading, such routines tend to be more difficult to
debug and maintain.
To improve run-time performance, GT.M tends to move work from run-time to
compile-time. Indirection forces compiler actions to occur at run-time,
which minimizes the benefits of compilation.
M allows most forms of indirection to be recursive. However, in real
applications, recursive indirection typically makes the code obscure and
slow.
There are circumstances where indirection serves a worthwhile purpose. For
instance, certain utility functions with a general nature may be clearly
abstracted and coded using indirection. Because M has no "CASE" command,
DO (or GOTO) with argument indirection provides a clear solution to the
problem of providing complex branching.
Some M users prototype with indirection and then replace indirection with
generated code that reduces run-time overhead. In any case, always
consider whether indirection can be replaced with a clearer or more
efficient approach.
Run-time errors from indirection or XECUTEs maintain $STATUS and $ZSTATUS
related information and cause normal error handling but do not provide
compiler supplied information on the location of any error within the code
fragment.
2 Parameter_Passing
Parameter Passing
Parameter passing provides a way of explicitly controlling some or all of
the variable context transferred between M routines.
M uses parameter passing for:
* A DO command with parameters
* Extrinsic functions and special variables
Parameter passing is optional on DO commands.
Parameter passing uses two argument lists: the actuallist that specifies
the parameters that M passes to an invoked routine, and the formalist that
specifies the local variables to receive or associate with the parameters.
3 Actuallists
Actuallists
An actuallist specifies the parameters M passes to the invoked routine.
The actuallist contains a list of zero or more parameters enclosed in
parentheses, immediately following a DO or extrinsic function.
An actuallist:
* Is made up of items separated by commas
* Contains expressions and/or actualnames. Items may be missing, that
is, two commas may appear next to each other, with nothing between
them.
* Must be used in an invocation of a label with a formallist, except in
the case of extrinsic special variables.
* Must not contain undefined variables.
* Must not have more items than a formallist with which it is used.
* May contain the same item in more than one position.
Example:
GTM>DO MULT(3,X,.RESULT)
3 Actualnames
Actualnames
An actualname starts with a leading period (.) delimiter, followed by an
unsubscripted local variable name. Actualnames identify variables that are
passed by reference, as described in a subsequent section. While
expressions in an actualname are evaluated when control is transferred to
a formallabel, the variables identified by actualnames are not; therefore,
they do not need to be defined at the time control is transferred.
3 Formallists
Formallists
A formallist specifies the variables M uses to hold passed values. A
formallist contains a list of zero or more parameters enclosed in
parentheses, immediately following a label.
Example:
MULT(MP,MC,RES)
SET RES=MP*MC
QUIT RES
3 Formallabel
Formallabel
A label followed by a formallist is called a formallabel.
3 Parameter_Passing_Operation
Parameter Passing Operation
M performs an implicit NEW on the formallist names and replaces the
formallist items with the actuallist items.
M provides the actuallist values to the invoked procedure by giving each
element in the formallist the value or reference provided by the
corresponding element in the actuallist. M associates the first name in
the formallist with the first item in the actuallist, the second name in
the formallist with the second item in the actuallist and so on. If the
actuallist is shorter than the formallist, M ensures that the formallist
items with no corresponding value are in effect NEWed. If the formallist
item has no corresponding item in the actuallist (indicated by two
adjacent commas in the actuallist), that item in the formallist becomes
undefined.
If the actuallist item is an expression and the corresponding formallist
variable is an array, parameter passing does not affect the subscripted
elements of the array. If an actualname corresponds to a formallist
variable, M reflects array operations on the formallist variable, by
reference, in the variable specified by the actualname.
M treats variables that are not part of the formallist as if parameter
passing did not exist (i.e., M makes them available to the invoked
routine).
M initiates execution at the first command following the formallabel.
A QUIT command terminates execution of the invoked routine. At the time of
the QUIT, M restores the formallist items to the values they had at the
invocation of the routine.
**Note**
In the case where a variable name appears as an actualname in the
actuallist, and also as a variable in the formallist, the restored value
reflects any change made by reference.
A QUIT from a DO does not take an argument, while a QUIT from an extrinsic
must have an argument. This represents one of the two major differences
between the DO command with parameters and the extrinsics. M returns the
value of the QUIT command argument as the value of the extrinsic function
or special variable. The other difference is that M stacks $TEST for
extrinsics.
Example:
SET X=30,Z="Hello"
DO WRTSQR(X)
ZWRITE
QUIT
WRTSQR(Z)
SET Z=Z*Z
WRITE Z,!
QUIT
Produces:
900
X=30
Z="Hello"
3 Parameter_Passing_Mechanisms
Parameter Passing Mechanisms
M passes the actuallist values to the invoked routine using two
parameter-passing mechanisms:
* Call-by-Value - where expressions appear
* Call-by-Reference - where actualnames appear
A call-by-value passes a copy of the value of the actuallist expression to
the invoked routine by assigning the copy to a formallist variable. If the
parameter is a variable, the invoked routine may change that variable.
However, because M constructs that variable to hold the copy, it deletes
the variable holding the copy when the QUIT restores the prior formallist
values. This also means that changes to the variable by the invoked
routine do not affect the value of the variable in the invoking routine.
Example:
SET X=30
DO SQR(X)
ZWRITE
QUIT
SQR(Z)SET Z=Z*Z
QUIT
Produces:
X=30
A period followed by a name identifies an actualname and causes a
call-by-reference.
A call-by-reference passes a pointer to the variable of the invoked
routine so operations on the assigned formallist variable also act on the
actualname variable. Changes, including KILLs to the formallist variable,
immediately have the same affect on the corresponding actualname variable.
This means that M passes changes to formallist variables in the invoked
routine back to the invoking routine as changes in actualname variables.
Example:
SET X=30
DO SQR(.X)
ZWRITE
QUIT
SQR(Z)SET Z=Z*Z
QUIT
Produces:
X=900
3 Parameter_Passing_Extensions
Parameter Passing Extensions
The standard does not provide for indirection of a labelref because the
syntax has an ambiguity.
Example:
DO @X(1)
This example could be:
* An invocation of the label specified by X with a parameter of 1.
* An invocation of the label specified by X(1) with no parameter list.
GT.M processes the latter interpretation as illustrated in the following
example.
Example:
The syntax:
SET A(1)="CUBE",X=5
DO @A(1)(.X)
WRITE X,!
QUIT
CUBE(C);cube a variable
SET C=C*C*C
QUIT
Produces the result:
125
GT.M follows analogous syntax for routine indirection:
DO ^@X(A) invokes the routine specified by X(A).
DO ^@(X)(A) invokes the routine specified by X and passes the parameter A.
DO ^@X(A)(A) invokes the routine specified by X(A) and passes the
parameter A.
2 External_Calls
External Calls
GT.M allows references to a GT.M database from programs written in other
programming languages that run under UNIX.
In GT.M, calls to C language routines may be made with the following
syntax:
DO &[packagename.]name[^name][parameter-list]
or as an expression element,
$&[packagename.]name[^name][parameter-list]
Where packagename, like the name elements is a valid M name. Because of
the parsing conventions of M, the identifier between the ampersand (&) and
the optional parameter-list has precisely constrained punctuation - a
later section describes how to transform this into a more richly
punctuated name should that be appropriate for the called function. While
the intent of the syntax is to permit the name^name to match an M
labelref, there is no semantic implication to any use of the caret (^).
**Note**
For more information on external calls, see Chapter 11: "Integrate
External".
2 Extrinsic_Functions
Extrinsic Functions
An extrinsic function is an M subroutine that another M routine can invoke
to return a value.
The format for extrinsic functions is:
$$[label][^routinename]([expr|.lname[,...]])
M stacks $TEST for extrinsic functions. This is one of the two major
differences between the DO command with parameters and extrinsics. On
return from an extrinsic function, M restores the value of $TEST to what
it was before the extrinsic function, regardless of the actions executed
by the invoked routine.
M requires a routine that implements an extrinsic function to terminate
with an explicit QUIT command which has an argument. M returns the value
of the QUIT command argument as the value of the extrinsic function. This
is the other major difference between the DO command with parameters and
extrinsics. It is now possible to invoke a C function in a package via the
external call mechanism.
Example:
POWER(V,X,S,T);extrinsic to raise to a power
;ignores fractional powers
SET T=1,S=0
IF X<0 SET X=-X,S=1
FOR X=1:1:X S T=T*V
QUIT $S(S:1/T,1:T)
GTM> WRITE $$^POWER(3,4)
81
GTM>
**Note**
The POWER routine uses a formallist that is longer than the "expected"
actuallist to protect local working variables. Such practice may be
encouraged or discouraged by your institution's standards.
2 Extrinsic_Special_Variables
Extrinsic Special Variables
An extrinsic special variable is a user-written M subroutine that another
M routine can invoke to return a value.
The format for extrinsic special variables is:
$$[label][^routinename]
An extrinsic special variable can be thought of as an extrinsic function
without input parameters. $$x is equivalent in operation to $$x().
Extrinsic special variables are the only case where invocation of a
formallabel does not require an actuallist. M stacks $TEST for extrinsic
special variables.
M requires that a routine that implements an extrinsic special variable
terminate with an explicit QUIT command which has an argument. M returns
the value of the QUIT command argument as the value of the extrinsic
special variable.
Example:
GTM>ZPRINT ^DAYOWEEK
DAYOWEEK();extrinsic special variable to
;provide the day of the week
QUIT $ZD($H,"DAY")
GTM>WRITE $$DAYOWEEK^DAYOWEEK
MON
2 Transaction_Processing
Transaction Processing
Transaction Processing (TP) provides a way for M programs to organize
database updates into logical groups that occur as a single event (i.e.,
either all the database updates in a transaction occur, or none of them
occur). No other process may behave as if it observed any intermediate
state.
Transaction processing has been designed to improve output and eliminate
"live lock" conditions. The number of attempts to complete the transaction
is limited to four. The fourth attempt is made inside a "critical section"
with all other processes temporarily locked out of the database. Between
the second and third tries, GT.M waits for a random interval between 0 and
500 milliseconds.
3 TP_Definitions
TP Definitions
In M, a transaction is a sequence of commands that begins with a TSTART
command, ends with a TCOMMIT command, and is not within the scope of
another transaction.
A successful transaction ends with a COMMIT that is triggered by the
TCOMMIT command at the end of the transaction. A COMMIT causes all the
database updates performed within the transaction to become available to
other processes.
An unsuccessful transaction ends with a ROLLBACK. ROLLBACK is invoked
explicitly by the TROLLBACK command, or implicitly at a process
termination that occurs during a transaction in progress. An error within
a transaction does not cause an implicit ROLLBACK. A ROLLBACK removes any
database updates performed within the transaction before they are made
available to other processes. ROLLBACK also releases all resources LOCKed
since the start of the transaction, and makes the naked reference
undefined.
A RESTART is a transfer of control to the TSTART at the beginning of the
transaction. RESTART implicitly includes a ROLLBACK and may optionally
restore local variables to the values they had when the initial TSTART was
originally executed. A RESTART always restores $TEST and the naked
reference to the values they had when the initial TSTART was executed.
RESTART does not manage device state information. A RESTART is invoked by
the TRESTART command or by M if it is determined that the transaction is
in conflict with other database updates. RESTART can only successfully
occur if the initial TSTART includes an argument that enables RESTART.
3 TP_Performance
TP Performance
To achieve the best GT.M performance, transactions should:
* be as short as possible
* consist, as much as possible, only of global updates
* be SERIAL with no associated LOCKs
* have RESTART enabled with a minimum of local variables protected by a
restart portion of the TSTART argument.
* Large concurrent transactions using TCOMMIT may result in repeated and
inefficient attempts by competing processes to capture needed scarce
resources, resulting in poor performance.
Example:
TSTART ():SERIAL
SET (ACCT,^M(0))=^M(0)+1
SET ^M(ACCT)=PREC,^PN(NAM)=ACCT
TCOMMIT
Example:
TSTART ():SERIAL
IF $TRESTART>3 DO QUIT
.TROLLBACK
.WRITE !,"Too many RESTARTs"
.QUIT
SET (NEXT,^ID(0))=^ID(0)+1
SET ^ID(NEXT)=RECORD,^XID(ZIP,NEXT)=""
TCOMMIT
1 Commands
Commands
This chapter describes M language commands implemented in GT.M. All
commands starting with the letter Z are GT.M additions to the ANSI
standard command set. The M standard specifies standard abbreviations for
commands and rejects any non-standard abbreviation.
2 Break
Break
The BREAK command pauses execution of the code and initiates Direct Mode.
The format of the BREAK command is:
B[REAK][:tvexpr] [expr[:tvexpr][,...]]
Issuing a BREAK command inside an M transaction destroys the Isolation of
that transaction. Because of the way that GT.M implements transaction
processing, a BREAK within a transaction may cause the transaction to
suffer an indefinite number of restarts ("live lock").
ZCONTINUE resumes execution of the interrupted program.
The VIEW "BREAKMSG" mask selectively enables or disables these messages.
By default, a process executing a GT.M image displays all BREAK messages.
3 Examples
Examples
Example:
LOOP0 F S act=$O(^act(act)) Q:act="" B:debug D LOOP1
This FOR loop contains a BREAK with a command postconditional.
Example:
GTM>ZPRINT ^br
br;
kill
for i=1:1:3 do break;
quit
break;
write "Iteration ",i,?15,"x=",$get(x,"<UNDEF>"),!
break:$data(x) "write ""OK"",!":x,"write ""Wrong again"",!":'x
set x=$increment(x,$data(x))
quit
GTM>DO ^br
Iteration 1 x=<UNDEF>
Iteration 2 x=0
%GTM-I-BREAK, Break instruction encountered
At M source location break+2^br
GTM>ZCONTINUE
Wrong again
%GTM-I-BREAK, Break instruction encountered
At M source location break+2^br
GTM>ZCONTINUE
Iteration 3 x=1
OK
%GTM-I-BREAK, Break instruction encountered
At M source location break+2^br
GTM>ZCONTINUE
%GTM-I-BREAK, Break instruction encountered
At M source location break+2^br
GTM>ZCONTINUE
GTM>
This uses a BREAK with both command and argument postconditionals. The
actions display debugging messages.
2 Close
Close
The CLOSE command breaks the connection between a process and a device.
The format of the CLOSE command is:
C[LOSE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
2 Do
Do
The DO command makes an entry in the GT.M invocation stack and transfers
execution to the location specified by the entryref.
The format of the DO command is:
D[O][:tvexpr] [entryref[(expr|.lvn[,...])][:tvexpr][,...]]
3 Examples
Examples
Example:
GTM>DO ^%RD
This example invokes the routine directory utility program (%RD) from
Direct Mode. The caret symbol (^) specifies that the DO command invokes
%RD as an external routine.
Example:
GTM>DO A(3)
This example invokes the subroutine at label A and passes the value 3 as a
parameter. The DO argument does not have a caret symbol (^), therefore, it
identifies A as a label in the current routine.
Example:
ReportA ; Label for ReportA
SET di="" OPEN outfile USE outfile
FOR SET di=$ORDER(^div(di)) QUIT:di="" DO PREP DO DO POST
.SET de="",(nr,gr)=0
.WRITE "Division ",di,! F S de=$ORDER(^de(di,de)) QUIT:de="" DO
..WRITE "Department ",de," Gross Rev: ",^grev(di,de),!
..WRITE "Department ",de," Net Rev: ",^nrev(di,de),!
..SET gr=gr+^grev(di,de),nr=nr+^nrev(di,de)
.W "Division Gross Rev: ",gr,!,"Division Net Rev: ",nr,!
DO PRINT^OUTPUT(outfile)
QUIT
Example:
GTM>zprint ^SQR
SQR(z);
set revert=0
if $view("undef") set revert=1 view "noundef"
if z="" write "Missing parameter.",! view:revert "undef" quit
else write z*z,! view:revert "undef" quit
GTM>do ^SQR(10)
100
GTM>do ^SQR
Missing parameter.
This examples demonstrates label invocations using DO with and without
parentheses.
2 Else
Else
ELSE executes the remainder of the line after the ELSE if $TEST is FALSE
(0). GT.M does not execute the rest of the line if $TEST is TRUE (1).
The format of the ELSE command is:
E[LSE]
ELSE is analogous to IF '$TEST, except the latter statement switches $TEST
to its complement and ELSE never alters $TEST.
3 Examples
Examples
Example:
If x=+x Set x=x+y
Else Write !,x
The IF command evaluates the conditional expression x=+x and sets $TEST.
If $TEST=1 (TRUE), GT.M executes the commands following the IF. The ELSE
on the following line specifies an alternative action to take if the
expression is false.
Example:
If x=+x Do ^GOFISH
Else Set x=x_"^"_y
The DO with an argument after the IF raises the possibility that the
routine ^GOFISH changes the value of $TEST, thus making it possible to
execute both the commands following the IF and the commands following the
ELSE.
Example:
Open dev::0 Else Write !,"Device unavailable" QUIT
This ELSE depends on the result of the timeout on the OPEN command. If the
OPEN succeeds, it sets $TEST to one (1) and GT.M skips the rest of the
line after the ELSE. If the OPEN fails, it sets $TEST to zero (0), and
GT.M executes the remainder of the line after the ELSE.
2 For
For
The FOR command provides a looping mechanism in GT.M. FOR does not
generate an additional level in the M standard stack model.
The format of the FOR command is:
F[OR][lvn=expr[:numexpr1[:numexpr2]][,...]]]
3 Examples
Examples
Example:
GTM>Kill i For i=1:1:5 Write !,i
1
2
3
4
5
GTM>Write i
5
GTM>
This FOR loop has a control variable, i, which has the value one (1) on
the first iteration, then the value two (2), and so on, until in the last
iteration i has the value five (5). The FOR terminates because
incrementing i would cause it to exceed the limit. Notice that i is not
incremented beyond the limit.
Example:
GTM>FOR x="hello",2,"goodbye" WRITE !,x
hello
2
goodbye
GTM>
This FOR loop uses the control variable x and a series of arguments that
have no increments or limits. Notice that the control variable may have a
string value.
Example:
GTM>For x="hello":1:-1 Write !,x
GTM>ZWRite x
x=0
GTM>
Because the argument has an increment, the FOR initializes the control
variable x to the numeric evaluation of "hello" (0). Then, GT.M never
executes the remainder of the line because the increment is positive, and
the value of the control variable (0) initializes to greater than the
limiting value (-1).
Example:
GTM>For y=-1:-3:-6,y:4:y+10,"end" Write !,y
-1
-4
-4
0
4
end
GTM>
Example:
GTM>Set x="" For Set x=$Order(ar(x)) Quit:x="" Write !,x
2 Goto
Goto
The GOTO command transfers execution to a location specified by its
argument.
The format of the GOTO command is:
G[OTO][:tvexpr] entryref[:tvexpr][,...]
3 Examples
Examples
Example:
GTM>GOTO TIME+4
This GOTO command transfers control from Direct Mode to the line that is
four (4) lines after the line labeled TIME (in the currently active
routine). Using an offset is typically a debugging technique and rarely
used in production code.
Example:
GOTO A:x<0,^A:x=0,A^B
This GOTO command transfers control to label A in the current routine, if
x is less than zero (0), to routine ^A if x is equal to zero (0), and
otherwise to label A in routine ^B. Once any of the transfers occurs, the
rest of the arguments have no effect.
2 Halt
Halt
The HALT command stops the program execution and cause GT.M to return
control to the operating system environment that invoked the GT.M image.
The format of the HALT command is:
H[ALT][:tvexpr]
Example:
$ gtm
GTM>HALT
$
Because we invoke this GT.M image interactively, the HALT in Direct Mode
leaves the process at the shell prompt.
2 Hang
Hang
The HANG command suspends GT.M program execution for a period of time
specified by the command argument.
The format of the HANG command is:
H[ANG][:tvexpr] numexpr[,...]
3 Examples
Examples
Example:
For Quit:$Data(^CTRL(1)) Hang 30
This FOR loop repeatedly tests for the existence of ^CTRL(1), and
terminates when that global variable exists. Otherwise the routine HANGs
for 30 seconds and tests again.
Example:
SET t=1 For Quit:$Data(^CTRL(1)) Hang t If t<30 Set t=t+1
This is similar to the previous example, except that it uses an adaptive
time that lengthens from 1 second to a limit of 30 seconds if the routine
stays in the loop.
2 If
If
The IF command provides conditional execution of the remaining commands on
the line. When IF has an argument, it updates $TEST with the truth value
of its evaluated argument. GT.M executes the remainder of a line after an
IF statement when $TEST is 1 (TRUE). When $TEST is 0 (FALSE), GT.M does
not execute the rest of the line.
The format of the IF command is:
I[F] [tvexpr[,...]]
Example:
IF A,B ...
is equivalent to
IF A IF B
An IF with more than one argument behaves as if those arguments were
logically "ANDed." However, execution of the line ceases with the
evaluation of the first false argument. For IF argument expressions
containing the "AND" operator (&), execution still ceases with the
evaluation of the first false argument. Any global references within the
expression act in sequence to maintain the naked reference.
3 Examples
Examples
Example:
IF x=+x!(x="") Do BAL
In this example, the DO executes if x contains a number or a null string.
Example:
Write !,?50,BAL If 'BAL Write "****"
IF Set EMPTY(acct)=""
The IF in the first line changes the value of $TEST, determining the
execution of the code following the argumentless IF in the second line.
Such argumentless IFs may serve as a form of line continuation.
Example:
GTM>Set X=1,Y=1,Z=2 Kill UNDEF
GTM>If X=1,Y=1,Z=3,UNDEF=0 Write "HI"
GTM>
The IF command causes GT.M to cease executing the line after it determines
Z is not equal to three (3). Therefore, GT.M never evaluates the reference
to the undefined variable and never generates an error.
Example:
GTM>Set X=1 Kill UNDEF
GTM>If X=1!(UNDEF=3) Write "HI"
HI
GTM>
2 Job
Job
The JOB command initiates another GT.M process that executes the named
routine.
$ZJOB is set to the pid of the process created by the JOB command.
The format of the JOB command is:
J[OB][:tvexpr] entryref[(expr[,...])]
[:[(keyword[=value][:...])][:numexpr]][,...]
3 The_JOB_Environment
The JOB Environment
When the JOB is forked, UNIX creates the environment for the new process
by copying the environment of the process issuing the JOB command and
making a few minor modifications. By default, the standard input is
assigned to the null device, the standard output is assigned to
routinename.mjo, and the standard error is assigned to routinename.mje.
3 JOB_Processparameters
JOB Processparameters
The following sections describe the processparameters available for the
JOB command in GT.M.
4 CMD[LINE]="strlit"
CMD[LINE]="strlit"
The string literal specifies the $ZCMDLINE of the JOB'd process.
4 DEF[AULT]=strlit
DEF[AULT]=strlit
The string literal specifies the default directory.
The maximum directory length is 255 characters.
If the JOB command does not specify a DEFAULT directory, GT.M uses the
current default directory of the parent process.
4 ERR[OR]=strlit
ERR[OR]=strlit
strlit specifies the stderr of the JOBbed process. strlit can either be a
file or a DETACHed socket (that is, a socket from the socket pool). To
pass a DETACHed socket as the stderr of the JOBbed process, specify strlit
in the form of "SOCKET:<handle>" where <handle> is the socket handle. On
successful completion of the JOBbed process, the passed socket is closed
and is no longer available to the parent process.
The maximum string length is 255 characters.
By default, JOB constructs the error file from the routinename using a
file extension of .mje: the default directory of the process created by
the JOB command.
4 GBL[DIR]=strlit
GBL[DIR]=strlit
The string literal specifies a value for the environment variable
gtmgbldir.
The maximum string length is 255 characters.
By default, the job uses the same specification for gtmgbldir as that
defined in $ZGBLDIR for the process using the JOB command.
4 IN[PUT]=strlit
IN[PUT]=strlit
strlit specifies the stdin of the JOBbed process. strlit can either be a
file or a DETACHed socket (that is, a socket from the socket pool). To
pass a DETACHed socket as the stdin of the JOBbed process, specify strlit
in the form of "SOCKET:<handle>" where <handle> is the socket handle. On
successful completion of the JOBbed process, the passed socket is closed
and is no longer available to the parent process.
**Note**
Specify a DETACHed socket in both INPUT and OUTPUT parameters to pass it
as the $PRINCIPAL of the JOBbed process.
The maximum string length is 255 characters.
GT.M does not supply a default file extension.
By default, the job takes its input from the null device.
4 OUT[PUT]=strlit
OUT[PUT]=strlit
strlit specifies the stdout of the JOBbed process. strlit can either be a
file or a DETACHed socket (that is, a socket from the socket pool). To
pass a DETACHed socket as the stdout of the job, specify strlit in the
form of "SOCKET:<handle>" where <handle> is the socket handle. On
successful completion of the JOBbed process, the passed socket is closed
and is no longer available to the parent process.
**Note**
Specify a DETACHed socket in both INPUT and OUTPUT parameters to pass it
as the $PRINCIPAL of the JOBbed process.
The maximum string length is 255 characters.
By default, JOB constructs the output file pathname from the routinename
using a file extension of .mjo and the current default directory of the
process created by the JOB command.
4 STA[RTUP]="/path/to/shell/script"
STA[RTUP]="/path/to/shell/script"
Specifies the location of the shell script that executes before running
the named routine.
The JOBbed process spawns a shell session to execute the shell script. If
the shell script fails, the JOB'd process terminates without running the
named routine. Because STARTUP executes in a separate shell, it has no
impact on the environment of the JOB'd process, which is inherited from
the parent. STARTUP is useful for actions such as creating directories.
Use PIPE devices instead of the JOB command to control the environment of
a spawned process.
3 Examples
Examples
Example:
GTM>JOB ^TEST("V54001","")
This creates a job that starts doing the routine ^TEST (with 2 parameters)
in the current working directory.
Example:
JOB PRINTLABELS(TYPE,PRNTR,WAITIM)
This passes three values (TYPE, PRNTR, and WAITIM) to the new job, which
starts at the label PRINTLABELS of the current routine.
Example:
Refer to the sockexamplemulti3.m program in "Socket Device
Examples" for more examples on the JOB command.
2 Kill
Kill
The KILL command deletes local or global variables and their descendant
nodes.
The format of the KILL command is:
K[ILL][:tvexpr] [glvn | (glvn[,...]) | *lname | *lvn ]
3 Examples
Examples
Example:
GTM>Kill Set a=0,a(1)=1,a(1,1)="under" KILL a(1) ZWR
a=0
GTM>
This uses an argumentless KILL to get a "fresh start" by deleting all
existing local variables. After SETting a, a(1), and a(1,1), the KILL
deletes a(1) and its descendants. The ZWRITE shows only a remaining.
Example:
GTM>Kill (a,b),^AB(a,b)
The first argument (an exclusive KILL) specifies to KILL all local
variables except a and b. The second argument deletes ^AB(a,b) and any
descendants of that global variable node.
Example:
kill *
write !,"gtm_stdxkill=",+$ztrnlnm("gtm_stdxkill"),!
set (A,B,C,E)="input"
do X(.A,.B)
zwrite
write !,"____________",!
set (A,B,C,E)="input"
do Y(.A,.B)
zwrite
write !,"____________",!
set (A,B,C,E)="base"
set *C=A,*D=B
kill (C,D)
zwrite
quit
X(C,D) set (C,D)="output"
kill (C,D)
quit
Y(C,D) set (C,D)="output"
kill (A,C,D)
quit
Produces the following output:
gtm_stdxkill=0
A="output"
B="output"
C="input"
____________
A="output"
B="output"
C="input"
____________
A="base" ;*
B="base" ;*
*C=A
*D=B
2 Lock
Lock
The LOCK command reserves and releases resource names, and provides a
semaphore capability for GT.M processes. This capability can be used for
interprocess synchronization and signaling.
Assigning a LOCK does not specify any explicit control over variables and
does not directly effect either read or write access to global (or local)
data. However, an application that adheres to clearly defined conventions
of LOCKing before any access can indirectly achieve such an effect.
FIS recommends implementing database Consistency using transaction
processing rather than LOCKs. If you wish to avoid GT.M's use of
optimistic concurrency for TP, place the LOCK just before the original
TSTART and release it after the final TCOMMIT.
The format of the LOCK command is:
L[OCK][:tvexpr] [[-|+]nref|(nref[,...])[:numexpr] [,...]]
2 Merge
Merge
The MERGE command copies a variable and all its descendants into another
variable. MERGE does not delete the destination variable, nor any of its
descendants.
The format of MERGE command is:
M[ERGE][:tvexpr] glvn1=glvn2[,...]
3 Examples
Examples
Example:
GTM>Set ^gbl1="one"
GTM>Set ^gbl1(1,1)="oneone"
GTM>Set ^gbl1(1,1,3)="oneonethree"
GTM>Set ^gbl1(1,2,4)="onetwofour"
GTM>Set ^gbl2(2)="gbl2_2"
GTM>Set ^gbl2(2,1,3)="gbl2_2_1_3"
GTM>Set ^gbl2(2,1,4,5)="gbl2_2_1_4_5"
GTM>Merge ^gbl1(1)=^gbl2(2)
GTM>WRITE $Reference
^gbl1(1)
GTM>ZWRite ^gbl1
^gbl1="one"
^gbl1(1)="gbl2_2"
^gbl1(1,1)="oneone"
^gbl1(1,1,3)="gbl2_2_1_3"
^gbl1(1,1,4,5)="gbl2_2_1_4_5"
^gbl1(1,2,4)="onetwofour"
GTM>ZWRITE ^gbl2
^gbl2(2)="gbl2_2"
^gbl2(2,1,3)="gbl2_2_1_3"
^gbl2(2,1,4,5)="gbl2_2_1_4_5"
GTM>
This example illustrates how MERGE copies a sub-tree of one global into
another. The nodes in the sub-tree of ^gbl(2), for which $DATA() value is
1 or 11, are copied to sub-tree of ^gbl1(1) as follows:
^gbl1(1) is updated from the value of ^gbl2(2)
^gbl1(1,1,3) is updated from the value of ^gbl2(2,1,3)
^gbl1(1,1,4,5) is updated from the value of ^gbl2(2,1,4,5)
Since ^gbl1(2,1) and ^gbl2(2,2,4) do not have values ($DATA()=0), the
corresponding nodes ^gbl1(1,1) and ^gbl(1,2,4) respectively are left
unchanged. The naked indicator takes the value ^gbl(1) as if SET replaced
MERGE. Notice that the MERGE command does not change ^gbl2(2) or its
descendants. Ancestor nodes of ^gbl(1) are also left unchanged.
Example:
GTM>Kill
GTM>Set ^gbl(1,2)="1,2"
GTM>Merge lcl(3,4)=^gbl(1)
GTM>Set ^("naked")=2
GTM>ZWRite ^gbl
^gbl(1,2)="1,2"
^gbl("naked")=2
GTM>ZWRite lcl
lcl(3,4,2)="1,2"
GTM>
This example illustrates how MERGE creates a sub-tree of a variable when
the variable does not exist. Also, notice how the naked indicator is set
when the source of the MERGE is a global and the destination a local.
2 New
New
The NEW command "stacks" copies of local variables and reinitializes those
variables. An explicit or implicit QUIT from a DO, XECUTE or extrinsic
function "unstacks" the NEWed variables, that is, restores the variable to
the stacked value. A NEW lasts only while the current scope of execution
is active.
The format of the NEW command is:
N[EW][:tvexpr] [[(]lvn[,...][)][,...]]
3 Examples
Examples
Example:
NEW1;
Set A(1)=1,B=4,C=5
Write !,"VARIABLES BEFORE NEW:",!
ZWRite
Do LABEL
Write !,"VARIABLES AFTER RETURN:",!
ZWRite
Quit
LABEL
New A Set C=7
Write !,"VARIABLES AFTER NEW:",!
ZWRite
Quit
Produces the results:
VARIABLES BEFORE NEW:
A(1)=1
B=4
C=5
VARIABLES AFTER NEW:
B=4
C=7
VARIABLES AFTER RETURN:
A(1)=1
B=4
C=7
Example:
NEW2;
Set (A,B,C,D)="TEST"
Do LABEL
Write !,"VARIABLES AFTER RETURN:",!
ZWRite
Quit
LABEL
New (B,C) SET (A,B,Z)="NEW"
Write !,"VARIABLES AFTER EXCLUSIVE NEW:",!
ZWRite
Quit
Produces the results:
VARIABLES AFTER EXCLUSIVE NEW:
A="NEW"
B="NEW"
C="TEST"
Z="NEW"
VARIABLES AFTER RETURN:
A="TEST"
B="NEW"
C="TEST"
D="TEST"
Example:
/usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^stackalias
stackalias ; Demonstrate New with alias
ZPrint ; Print this program
Set A=1,*B=A,*C(2)=A ; Create some aliases
Write "------------",!
Write "ZWRite in the caller before subprogram",!
ZWRite
Do S1 ; Call a subprogram
Write "------------",!
Write "ZWRite in the caller after subprogram - A association is restored",!
ZWRite
Quit
;
S1 ; Subprogram
New A
Set A="I am not an alias",B="I am an alias"
Write "------------",!
Write "ZWRite in the subprogram with new A and modified B",!
ZWRite
Quit
------------
ZWRite in the caller before subprogram
A=1 ;*
*B=A
C=3
*C(2)=A
D=4
------------
ZWRite in the subprogram with new A and modified B
A="I am not an alias"
B="I am an alias" ;*
C=3
*C(2)=B
D=4
------------
ZWRite in the caller after subprogram - A association is restored
A="I am an alias" ;*
*B=A
C=3
*C(2)=A
D=4
The following is essentially the same as the prior example but using an
exclusive NEW:
$ /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^stackalias1
stackalias1 ; Demonstrate New with alias
ZPrint ; Print this program
Set A=1,*B=A,*C(2)=A ; Create some aliases
Write "------------",!
Write "ZWRite in the caller before subprogram",!
ZWRite
Do S1 ; Call a subprogram
Write "------------",!
Write "ZWRite in the caller after subprogram - A association is restored",!
ZWRite
Quit
;
S1 ; Subprogram
New (B)
Set A="I am not an alias",B="I am an alias"
Write "------------",!
Write "ZWRite in the subprogram - Notice B is flagged as an alias",!
ZWRite
Quit
------------
ZWRite in the caller before subprogram
A=1 ;*
*B=A
C=3
*C(2)=A
D=4
------------
ZWRite in the subprogram - Notice B is flagged as an alias
A="I am not an alias"
B="I am an alias" ;*
------------
ZWRite in the caller after subprogram - A association is restored
A="I am an alias" ;*
*B=A
C=3
*C(2)=A
D=4
An exclusive New can create a scope in which only one association between
a name or an lvn and an array may be visible. In this case, ZWRITE
nevertheless shows the existence of an alias, even when that array is
accessible from only one name or lvn.
2 Open
Open
The OPEN command creates a connection between a GT.M process and a device.
The format of the OPEN command is:
O[PEN][:tvexpr] expr[:[(keyword[=expr][:...])] [:numexpr]][,...]
2 Quit
Quit
Except when a QUIT appears on a line after a FOR, the QUIT command
terminates execution of the current GT.M invocation stack level initiated
by a DO, XECUTE, extrinsic function or special variable, and return
control to the next "lower" level. In this case, QUIT restores any values
stacked at the current level by NEWs or by parameter passing. A QUIT
command terminates any closest FOR command on the same line. Note that M
overloads the QUIT command to terminate DO, FOR, XECUTE and extrinsics
($$) of which FOR is the most different.
The format of the QUIT command is:
Q[UIT][:tvexpr] [expr | *lname | *lvn]
3 Examples
Examples
Example:
Do A
Quit
A Write !,"This is label A"
The explicit QUIT at the line preceding the label A prevents line A from
executing twice. The sub-routine at line A terminates with the implicit
QUIT at the end of the routine.
Example:
Write $$ESV
Quit
ESV()
QUIT "value of this Extrinsic Special Variable"
Because the label ESV has an argument list (which is empty), GT.M can only
legally reach that label with an extrinsic invocation. The QUIT on the
second line prevents execution from erroneously "falling through" to the
line labeled ESV. Because ESV identifies a subroutine that implements an
extrinsic special variable, the QUIT on the line after ESV has an argument
to provide the value of the extrinsic.
Example:
Set x="" For Set x=$Order(^BAL(x)) Quit:x]]"AR5999"!'$Length(x) DO STF
The postconditional QUIT terminates the FOR loop. Note the two spaces
after the QUIT because it has no argument.
2 Read
Read
The READ command transfers the input from the current device to a global
or local variable specified as a READ argument. For convenience, READ also
accepts arguments that perform limited output to the current device.
The format of the READ command is:
R[EAD][:tvexpr] (glvn|*glvn|glvn#intexpr)[:numexpr]|strlit|fcc[,...]
2 Set
Set
SET assigns values to variables or to a selected portion of a variable.
The format of the SET command is:
S[ET][:tvexpr] setleft=expr | (setleft[,...])=expr | *lvn=lname | aliascontainer[,...]
where
setleft == glvn | $EXTRACT(glvn,[,intexpr1[,intexpr2]]) | $PIECE(glvn,expr1[,intexpr1[,intexpr2]]) | isv
and
aliascontainer == lvn | exfunc | exvar
3 Examples
Examples
Example:
GTM>Kill Set a="x",(b,c)=1,@a="hello" ZWRite
a=x
b=1
c=1
x="hello"
GTM>
The KILL command deletes any previously defined local variables. The SET
command has three arguments. The first shows a simple direct assignment.
The second shows the form that assigns the same value to multiple
variables. The third shows atomic indirection on the left of the equal
sign. The ZWRITE command displays the results of the assignments.
Example:
GTM>Set ^(3,4)=^X(1,2)
As GT.M evaluates the right-hand side of the equal sign before the
left-hand side within a SET argument, the right-hand expression determines
the naked reference indicator prior to evaluation of the left-hand side.
Therefore, this example assigns ^X(1,3,4) the value of ^X(1,2).
Example:
GTM>Kill x Set $Piece(x,"^",2)="piece 3" ZWRite x
x="^^piece 3"
GTM>
This SET demonstrates a "set piece" and shows how SET generates missing
delimiters when required.
Example:
GTM>Set x="I love hotdogs"
GTM>Set $Extract(x,3,6)="want"
GTM>Write x
I want hotdogs
GTM>Set $Extract(x,7)=" many "
GTM>Write x
I want many hotdogs
GTM>
The SET $EXTRACT command replaces and extracts the specified characters
with the value of the expression on the right hand side of the equal-sign
(=).
Example:
GTM>kill A,B
GTM>set A=1,A(1)=1,A(2)=2
GTM>set *B=A ; A & B are aliases.
GTM>zwrite B
B=1 ;*
B(1)=1
B(2)=2
GTM>
This SET * command creates an alias associated between A and B. It
associates the entire tree of nodes of A including its root and all
descendants with B.
Example:
GTM>kill A,B,C
GTM>set A=1,*C(2)=A ; C(2) is a container
GTM>zwrite
A=1 ;*
*C(2)=A
GTM>set *B=C(2) ; B is now an alias
GTM>write B,":",$length(C(2)),":" ; An alias variable provides access but a container doesn't
1:0:
GTM>
This SET * command creates an alias by dereferencing an alias container.
2 TCommit
TCommit
The TCOMMIT command marks the end of a transaction or sub-transaction and
decrements $TLEVEL. If TCOMMIT marks the end of a transaction (decrements
$TLEVEL to zero), it invokes a COMMIT, which makes the database updates
performed by the transaction generally available. A TCOMMIT issued when no
transaction is in progress ($TLEVEL=0) produces an error.
The format of the TCOMMIT command is:
TC[OMMIT][:tvexpr]
For an example of the use of the TCOMMIT command, refer to the chapter on
General Language Features of M in GT.M Programmer's Guide.
2 TREstart
TREstart
The TRESTART command attempts to RESTART the current transaction. A
RESTART transfers control back to the initial TSTART and restores much of
the process state to what it was when that TSTART was originally executed.
A TRESTART issued when no transaction is in progress ($TLEVEL=0) or when
the transaction does not have RESTART enabled produces an error.
A TRESTART command causes the TP transaction to RESTART in the same way
that GT.M uses to implicitly restart the transaction in case of resource
conflicts. All restarts increment the internal transaction retry count to
a maximum of three (3), at which point, GT.M performs the entire TP
transaction within a critical section on all databases referenced in the
transaction.
GT.M issues a TRESTMAX runtime error when application code attempts a
TRESTART more than once during a transaction while $TRESTART=4 (note: in
order to be wholesome, TRESTART usage in application code should always be
conditional). In the final retry, GT.M holds the critical section lock on
all databases involved in the transaction. Since a TRESTART cancels all
the work done in the current transaction and transfers control back to the
TSTART, limiting the number of times this can be done in the final retry
limits the time a process can (by virtue of holding a critical section
lock on the databases) prevent other processes from updating the database.
GT.M limits TP restarts in the final retry due to non-availability of
M-locks in a similar fashion. GT.M allows a maximum of 16 such restarts
after which it issues a TPLOCKRESTMAX runtime error.
The format for the TRESTART command is:
TRE[START][:tvexpr]
For an example of the use of the TRESTART command, refer to the chapter on
"General Language Features of M" in the GT.M Programmer's Guide.
2 TROllback
TROllback
The TROLLBACK command terminates a transaction by causing a ROLLBACK,
which removes all database updates performed within a transaction. A
TROLLBACK without an argument also sets $TLEVEL and $TRESTART to zero (0).
Issuing a TROLLBACK when no transaction is in progress ($TLEVEL=0)
produces an error.
The format of the TROLLBACK command is:
TRO[LLBACK][:tvexpr] [intexpr]
For an example of the use of the TROLLBACK command, refer to the chapter
on "General Language Features of M" in the GT.M Programmer's Guide.
2 TStart
TStart
The TSTART command marks the beginning of a transaction or sub-transaction
and increments $TLEVEL. When TSTART marks the beginning of a transaction
($TLEVEL=1), its arguments determine whether the transaction may RESTART
and whether serializability is enforced. If a transaction may RESTART, the
TSTART arguments determine which local variables are restored during a
RESTART. Serializability is enforced by LOCK commands or, if the SERIAL
keyword is specified, by GT.M.
The format of the TSTART command is:
TS[TART][:tvexpr] [([lvn...])|lvn|*|][:keyword|(keyword...)]
For an example of the TSTART command, refer to the chapter on "General
Language Features of M" in the GT.M Programmer's Guide.
3 S[ERIAL]
S[ERIAL]
The SERIAL keyword indicates that GT.M must ensure the serializability of
the transaction. Note that GT.M always serializes transactions regardless
of the SERIAL keyword. On a nested TSTART, this portion of the argument is
irrelevant.
3 T[RANSACTIONID]=expr
T[RANSACTIONID]=expr
The TRANSACTIONID keyword declares an arbitrary transaction
identification.
If TRANSACTIONID="BATCH" or "BA" at transaction completion, the process
immediately continues execution. When a process issues a [final] TCOMMIT
for a transaction and journaling is active, by default the process waits
until the entire transaction is written to the journal file(s) before
executing the next command. This ensures that every transaction is durable
before the process moves on to the next step. Transactions flagged as
"BATCH" have lower latency and higher throughput, but a lower guarantee of
durability. Normally this flag is used when operational procedures (such
as a backup) or application code (such as a checkpoint algorithm) provides
an acceptable alternative means of ensuring durability.
2 Use
Use
The USE command selects the current device for READs (input) and WRITEs
(output).
The format of the USE command is:
U[SE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
2 View
View
The VIEW command adjusts an environmental factor selected by a keyword
argument. For example, VIEW controls journal buffer flushing, determines
whether GT.M reports undefined variables as errors or treats them as null,
and determines which BREAK commands should display messages.
The format of the VIEW command is:
V[IEW][:tvexpr] keyword[:expr2[:...]][,...]
3 Key_Words
Key Words
4 BREAKMSG
BREAKMSG
"BREAKMSG":value
Sets the value of the BREAK message mask. When GT.M processes a BREAK
command, the BREAK message mask controls whether to display a message
describing the source of the BREAK.
The mask uses the following four values that are added together to provide
the BREAKMSG value.
1 - BREAKs within the body of a program
2 - BREAKs within a ZBREAK action
4 - BREAKs within a device EXCEPTION
8 - BREAKs within a ZSTEP action
16 - ZBREAKs within a trigger removed due to updated trigger
(TRIGZBREAKREM)
The default BREAKMSG mask is 31 (1+2+4+8+16) which means that GT.M
displays all BREAK messages.
Example:
GTM>VIEW "BREAKMSG":5
In this example the BREAKMSG value is 5, representing the sum of 1 and 4.
This enables BREAKS within the body of a program (value 1) and for a
device EXCEPTION (value 4).
4 BADCHAR
BADCHAR
Enables or disable the gneration of an error when character-oriented
functions encounter malformed byte sequences (illegal characters).
At process startup, GT.M initializes BADCHAR from the environment variable
gtm_badchar. Set the environment variable $gtm_badchar to a non-zero
number or "YES" (or "Y") to enable VIEW "BADCHAR". Set the environment
variable $gtm_badchar to 0 or "NO" or "FALSE" (or "N" or "F") to enable
VIEW "NOBADCHAR". By default, GT.M enables VIEW "BADCHAR".
With VIEW "BADCHAR", GT.M functions generate the BADCHAR error when they
encounter malformed byte sequences. With this setting, GT.M detects and
clearly reports potential application program logic errors as soon as they
appear. As an illegal UTF-8 character in the argument of a
character-oriented function likely indicates a logic issue, FIS recommends
using VIEW "BADCHAR" in production environments.
**Note**
When all strings consist of well-formed characters, the value of VIEW
[NO]BADCHAR has no effect whatsoever. With VIEW "NOBADCHAR", the same
functions treat malformed byte sequences as valid characters. During the
migration of an application to add support for Unicode, illegal character
errors are likely to be frequent and indicative of application code that
is yet to be modified. VIEW "NOBADCHAR" suppresses these errors at times
when their presence impedes development.
4 DBFLUSH
DBFLUSH
"DBFLUSH"[:REGION[:N]]
When using the BG access method, writes modified blocks in the global
buffers to the database file. By default, this command option operates on
all regions under the current global directory. N specifies the number of
blocks to write; by default, DBFLUSH writes all modified blocks. Normally
GT.M schedules block flushing at appropriate times, but this option exists
for an application to explore the impact of flushing on their work load.
See also the DBSYNC and EPOCH VIEW Options.
4 DBSYNC
DBSYNC
"DBSYNC":REGION
Performs a file system hardening sync - fsync() - operation on the
database file. By default, this command option operates on all regions
under the current global directory. Normally GT.M schedules block flushing
at appropriate times, but this option exists for an application to explore
the impact of file hardening on their work load. See also the DBFLUSH and
EPOCH VIEW Options.
4 DMTERM
DMTERM
Provides a mechanism to retain default line terminators for direct mode
user interaction (including the BREAK command) independent of any
TERMINATOR deviceparameter changes for $PRINCIPAL. With VIEW "NODMTERM",
TERMINATOR deviceparameter apply to both READs from $PRINCIPAL and direct
mode interactions. A case-insensitive value of the environment variable
gtm_dmterm is "1", "yes", or "true" establishes a NODMTERM state at
process initiation; all other values, including no value, result in the
default VIEW "NODMTERM" behavior. $VIEW("DMTERM") returns 1 for DMTERM
mode or 0 for NODMTERM mode.
4 EPOCH
EPOCH
"EPOCH"[:REGION]
Flushes the database buffers and, if journaling is enabled, writes an
EPOCH record. By default, this command option operates on all regions
under the current global directory. Normally GT.M schedules epochs as a
user controlled journaling characteristic, but this option exists for an
application to explore the impact of epochs on their work load. See also
the DBFLUSH and DBSYNC VIEW Options. Epochs include DBFLUSH and DBSYNC
actions, but performing them before the epoch may reduce the duration of
these actions within the epoch.
4 FULL_BOOLEANWARN
FULL_BOOLEANWARN
Controls the evaluation of Boolean expressions (expressions evaluated as a
logical TRUE or FALSE).
By default, GT.M enables VIEW "NOFULL_BOOLEAN" which means that GT.M stops
evaluating a Boolean expression as soon as it establishes a definitive
result. For example, neither 0&$$abc^def() nor 1!$$abc^def() executes
$$abc^def(). However, in the case of global references, such as 0&^a or
1!^a, GT.M sets $reference and the naked indicator without actually
accessing the global variable.
With VIEW "FULL_BOOLEAN", GT.M ensures that all side effect expression
atoms, extrinsic functions ($$), external functions ($&), and $INCREMENT()
execute in left-to-right order.
With VIEW "FULL_BOOLWARN", GT.M not only evaluates Boolean expressions
like "FULL_BOOLEAN" but produces a BOOLSIDEFFECT warning when it
encounters Boolean expressions that may induce side-effects; that is:
expressions with side effects after the first Boolean operator - extrinsic
functions, external calls and $INCREMENT().
GT.M picks up the value of [NO]FULL_BOOL[EAN][WARN] from the environment
variable gtm_boolean. If gtm_boolean is undefined or evaluates to an
integer zero (0), the initial setting the default "NOFULL_BOOLEAN", if it
evaluates to an integer one (1), the initial setting is "FULL_BOOLEAN" and
if it evaluates to integer two (2) the initial setting is "FULL_BOOLWARN".
VIEW "NOFULLBOOLEAN" produces an error when gtm_side_effects is on. For
more information on the gtm_side_effects environment variable, refer to
the Environment Variables section in the Basic Operations chapter of the
Administration and Operations Guide.
4 GDSCERT
GDSCERT
Enables (value=1) or disables (value=0) database block certification.
Database block certification causes GT.M to check the internal integrity
of every block as it writes the block. Block certification degrades
performance and exists primarily as a tool for use by FIS. The default is
GDSCERT:0.
4 GVDUPSETNOOP
GVDUPSETNOOP
Enables (VIEW "GVDUPSETNOOP":1) or disables (VIEW "GVDUPSETNOOP":0)
duplication set optimization.
Duplicate set optimization prevents a SET that does not change the value
of an existing node from performing the update or executing any trigger
code specified for the node. By default, duplicate set optimization is
enabled.
4 JNLFLUSH
JNLFLUSH
Writes or flushes journaling buffers associated with the given region to
permanent storage, for example, to disk. If the VIEW "JNLFLUSH" does not
specify the optional region, GT.M flushes all journaled regions of the
current Global Directory.
Normally GT.M writes journal buffers when it completes a transaction
(unless TRANSACTIONID="BATCH"), fills the journal buffer or when some
period of time passes with no journal activity.
4 JNLWAIT
JNLWAIT
Causes a process to pause until its journaling buffers have been written.
JNLWAIT ensures that GT.M successfully transfers all database updates
issued by the process to the journal file before the process continues.
Normally, GT.M performs journal buffer writes synchronously for TP
updates, and asynchronously, while the process continues execution, for
non-TP updates or TP updates with TRANSACTIONID=BATCH.
4 JOBPID
JOBPID
Enables (value=1) or disables (value=0) the addition of the child process
ID to the output and error filenames generated by the JOB command. The
default is 0.
The value=1 option prevents output files generated by the JOB command from
being overwritten each time a new job is spawned from the GT.M source
file.
4 LABELS
LABELS
Enables (value="LOWER") or disables (value="UPPER") case sensitivity for
labels within routines.
It is important to have the same case handling at compile-time and
run-time.
Because GT.M stores routines as regular files and file names are case
sensitive on UNIX, GT.M always treates routine names as case sensitive.
4 LINK
LINK
Enables ("LINK":"RECURSIVE") or disables ("LINK":"RECURSIVE") the ZLINK
command to accept and relink routines on the GT.M invocation stack. With
VIEW "LINK":"RECURSIVE" specified, the ZLINK command adds an executable
routine even when a routine with the same name is active and available in
the current stack. When a process links a routine with the same name as an
existing routine, future calls use the new routine. Prior versions of that
routine referenced by the stack remain tied to the stack until they QUIT,
at which point they become inaccessible. This provides a mechanism to
patch long-running processes.
The default is VIEW "LINK":"NORECURSIVE".
4 LOGTPRESTART
LOGTPRESTART
Allows a process to dynamically change the logging of TPRESTART messages
to the operator log established at process startup by the environment
variables gtm_tprestart_log_delta and gtm_tprestart_log_first.
VIEW "NOLOGTPRESTART" turns off the logging of TPRESTART messages to the
operator log.
VIEW "LOGTPRESTART"[=intexpr] turns on logging of TPRESTART messages to
the operator log. If no intexpr is specified, GT.M uses the value of
environment variable gtm_tprestart_log_delta, if it is defined, and one
otherwise (that is, every transaction restart will be logged). A negative
value of intexpr turns off the logging of TPRESTART messages.
Note that it is not possible to perform the operations of
gtm_tprestart_log_first with VIEW "LOGTPRESTART"[=intexpr].
4 LV_GCOL
LV_GCOL
Starts a data-space garbage collection, which normally happens
automatically at appropriate times.
**Note**
There are no visible effects from LV_GCOL, LV_REHASH, and STP_GCOL except
for the passage of time depending on the state of your process. FIS uses
these VIEW "LV_GCOL","LV_REHASH","STP_GCOL" facilities in testing. They
are documented to ensure completeness in product documentation. You may
(or may not) find them useful during application development for debugging
or performance testing implementation alternatives.
4 LV_REHASH
LV_REHASH
Starts a reorganization of the local variable look-up table, which
normally happens automatically at appropriate times.
**Note**
There are no visible effects from LV_REHASH, LV_GCOL, and STP_GCOL except
for the passage of time depending on the state of your process. FIS uses
these VIEW "LV_GCOL","LV_REHASH","STP_GCOL" facilities in testing. They
are documented to ensure completeness in product documentation. You may
(or may not) find them useful during application development for debugging
or performance testing implementation alternatives.
4 NEVERLVNULLSUB
NEVERLVNULLSUB
[NEVER]|[NO]LVNULLSUBS
Disallows, partially disallows, or allows local arrays to have empty
string subscripts. The default is LVNULLSUBS.
NOLVNULLSUBS disallows any variant of SET to operate on a local array
having an empty string subscript.
NEVERLVNULLSUBS disallows any variant of SET or KILL
($DATA(),$GET(),$ORDER(), and $QUERY()) to operate on a local array having
an empty string subscript. An empty string as the last subscript in
$ORDER() and $QUERY() has the semantic significance of requesting the next
lexical item and is not subject to NULLSUBS errors.
LVNULLSUBS allows local arrays to have empty string subscripts.
At process startup, GT.M initializes [NEVER][NO]LVNULLSUBS from
$gtm_lvnullsubs. Set the environment variable $gtm_lvnullsubsv to:
**Important**
Remember that for global variables, empty string subscript checking is
controlled by a database region characteristic. FIS recommends using
LVNULLSUBS, NOLVNULLSUBS, or NEVERLVNULLSUBS for local variables and
NULLSUBS options ALWAYS or NEVER for global variables.
4 NOISOLATION
NOISOLATION
where expr must evaluate to one of the following forms
* "", that is, the empty string : turn off the feature for all globals
for which it has previously been turned on
* "^gvn1,^gvn2,..." : turn on the feature for the globals in the list,
turning it off for globals for which it has previously been turned on
* "+^gvn1,^gvn2,..." : add these globals to the list of globals that
have this feature turned on
* "-^gvn1,^gvn2,..." : turn off the feature for these globals leaving
the status for other globals unchanged
4 PATCODE
PATCODE
"PATCODE":"tablename"
Identifies the alternative table of unique patterns for use with the "?"
operator to be loaded from the pattern definition file. For additional
information, refer to the "Internationalization" chapter in the GT.M
Programmer's Guide.
4 PATLOAD
PATLOAD
Identifies the file containing definitions of unique patterns for use with
the "?" operator. These pattern definitions can be used in place of, or in
addition to, the standard C, N, U, L, and P.
4 RCTLDUMP
RCTLDUMP
Displays the created relinkctl files and the routines looked for in their
related directories. An entry in these files does not mean that a given
routine was found there. It merely means it was looked for there and shows
a cycle number (which ZRUPDATE bumps) whose change indicates a new
published version of the given object file. As it is a diagnostic tool for
the new feature, FIS may remove or modify this VIEW option in subsequent
releases.
4 RESETGVSTATS
RESETGVSTATS
Resets all the process-private global access statistics to 0. This is
particularly useful for long running processes which would periodically
like to restart the counting without requiring a shut down and restart.
4 STP_GCOL
STP_GCOL
Starts a string-pool garbage collection, which normally happens
automatically at appropriate times.
**Note**
There are no visible effects from STP_GCOL, LV_GCOL and LV_REHASH except
for the passage of time depending on the state of your process. FIS uses
these VIEW "LV_GCOL","LV_REHASH","STP_GCOL" facilities in testing. They
are documented to ensure completeness in product documentation. You may
(or may not) find them useful during application development for debugging
or performance testing implementation alternatives.
4 UNDEF
UNDEF
Enables or disables handling of undefined variables as errors. With UNDEF,
GT.M handles all references to undefined local or global variables as
errors. With NOUNDEF, GT.M handles all references to undefined local or
global variables as if the variable had a value of the empty string. In
other words, GT.M treats all variables appearing in expressions as if they
were the argument of an implicit $GET(). UNDEF is the default.
The environment variable $gtm_noundef specifies the initial value value of
[NO]UNDEF at process startup. If it is defined, and evaluates to a
non-zero integer or any case-independent string or leading substring of
"TRUE" or "YES", then GT.M treats undefined variables as having an
implicit value of an empty string.
**Note**
NOUNDEF does not apply to an undefined FOR control variable. This prevents
an increment (or decrement) of an undefined FOR control variable from
getting into an unintended infinite loop. For example, FOR A=1:1:10 KILL A
gives an UNDEF error on the increment from 1 to 2 even with VIEW
"NOUNDEF".
4 TRACE
TRACE
Traces GT.M program execution and generates profiling information about
the lines and functions executed; with low impact on the run-time
performance.
The feature turns on (value=1) or turns off (value=0) M-profiling. This
expression must evaluate to a string containing the name of a GT.M global
variable. The global may also have subscripts; however the subscripts must
be literals or the special variable $JOB.
The expression is optional when turning M-profiling off, if it exists, it
overrides the global variable set when M-profiling was turned on.
gtm_trace_gbl_name enables GT.M tracing at process startup. Setting
gtm_trace_gbl_name to a valid global variable name instructs GT.M to
report the data in the specified global when a VIEW command disables the
tracing, or implicitly at process termination. This setting behaves as if
the process issued a VIEW "TRACE" command at process startup. However,
gtm_trace_gbl_name has a capability not available with the VIEW command,
such that if the environment variable is defined but evaluates to zero (0)
or, only on UNIX, to the empty string, GT.M collects the M-profiling data
in memory and discards it when the process terminates (this feature is
mainly used for in-house testing). Note that having this feature activated
for process that otherwise do not open a database file (such as GDE) can
cause them to encounter an error.
Example:
GTM>zprint ^profiling
; In this example, query^profiling, order^profiling, and merge^profling perform the same operation -- store even-numbered subscripts of a global to a subscripted loc
al variable. M-profiling results show which yields the fastest execution between the three.
profiling
kill ^TMP,^trc
view "trace":1:"^trc"
set ulimit=1500
for i=1:1:ulimit set ^TMP(i)=i
do qom("^TMP")
view "trace":0:"^trc"
zwrite ^trc
quit
qom(y)
do query(y)
do order(y)
do merge(y)
quit
query(y)
new i,qryval
set i=0,y=$query(@y)
for quit:y="" do
. set:i#2 qryval(i)=@y
. set y=$query(@y)
. set i=i+1
quit
order(y)
new i,ordval
set x="",i=0,y=y_"(x)",x=$order(@y)
for quit:x="" do
. set:i#2 ordval(i)=x
. set x=$order(@y)
. set i=i+1
quit
merge(y)
new i,merval
set i=0,merval=0
merge merval=@y
for i=1:1:$order(merval(""),-1) do
. kill:i#2 merval(i)
quit
On a Ubuntu system running GTM V6.1-000_x86_64, this example produces an
output like the following:
GTM>do ^profiling
^trc("*CHILDREN")="0:0:0"
^trc("*RUN")="144009:76004:220013"
^trc("profiling","merge")="1:8001:12000:20001:16231"
^trc("profiling","merge",0)="1:0:0:0:5"
^trc("profiling","merge",1)="1:0:0:0:4"
^trc("profiling","merge",2)="1:0:0:0:4"
^trc("profiling","merge",3)="1:8001:0:8001:8044"
^trc("profiling","merge",4)="1:0:12000:12000:7992"
^trc("profiling","merge",4,"FOR_LOOP",1)=1500
^trc("profiling","merge",5)="1500:0:0:0:4"
^trc("profiling","merge",6)="1:0:0:0:174"
^trc("profiling","order")="1:12001:8001:20002:25720"
^trc("profiling","order",0)="1:0:0:0:8"
^trc("profiling","order",1)="1:0:0:0:6"
^trc("profiling","order",2)="1:0:0:0:90"
^trc("profiling","order",3)="1:0:8001:8001:7160"
^trc("profiling","order",3,"FOR_LOOP",1)=1501
^trc("profiling","order",4)="1500:0:0:0:6319"
^trc("profiling","order",5)="1500:12001:0:12001:12069"
^trc("profiling","order",6)="1500:0:0:0:0"
^trc("profiling","order",7)="1:0:0:0:63"
^trc("profiling","profiling",3)="1:0:0:0:9"
^trc("profiling","profiling",4)="1:52003:20001:72004:74499"
^trc("profiling","profiling",4,"FOR_LOOP",1)=1500
^trc("profiling","profiling",5)="1:0:0:0:14"
^trc("profiling","profiling",6)="1:0:0:0:10"
^trc("profiling","qom")="1:0:0:0:78"
^trc("profiling","qom",0)="1:0:0:0:18"
^trc("profiling","qom",1)="1:0:0:0:11"
^trc("profiling","qom",2)="1:0:0:0:9"
^trc("profiling","qom",3)="1:0:0:0:11"
^trc("profiling","qom",4)="1:0:0:0:5"
^trc("profiling","query")="1:72004:20001:92005:88031"
^trc("profiling","query",0)="1:0:0:0:5"
^trc("profiling","query",1)="1:0:0:0:14"
^trc("profiling","query",2)="1:0:0:0:108"
^trc("profiling","query",3)="1:12000:0:12000:7625"
^trc("profiling","query",3,"FOR_LOOP",1)=1501
^trc("profiling","query",4)="1500:8000:0:8000:28256"
^trc("profiling","query",5)="1500:52004:20001:72005:51919"
^trc("profiling","query",6)="1500:0:0:0:0"
^trc("profiling","query",7)="1:0:0:0:85"
o CPU times are reported in microseconds. 1 second = 1,000,000
microseconds.
o ^trc("*CHILDREN")="0:0:0" indicates that the main process did not
spawn any child process.
o ^trc("*RUN")="144009:76004:220013" : the three pieces specify the
aggregate User Time, System Time and Total Time values for the main
process.
o ^trc("profiling","query",3,"FOR_LOOP",1)=1501 specifies the number of
times the FOR loop was executed on line #3 of query^profiling.
o ^trc("profiling","merge")="1:8001:12000:20001:16231",
^trc("profiling","order")="1:12001:8001:20002:25720",
^trc("profiling","query")="1:72004:20001:92005:88031": the five pieces
specify the aggregate Execution Count, User Time, System,Time, Total
Time and the Elapsed Time of the code execution for merge^profiling,
order^profling, and query^profiling. merge^profiling has the fastest
execution time followed by order^profiling. query^profiling is the
slowest amongst the three.
o ^trc("profiling","merge",3)="1:8001:0:8001:8044" and others like it
specifies the cumulative Execution Count, User Time, System Time,
Total Time and the Elapsed Time of the code execution of line 3 of
merge^profiling.
o The M-profiling results are subject to the granularity of the
operating system provided time functions. CPU time entries having
0:0:0 values indicate lightweight M mode having 0 to less than 1
microsecond.
Consider the following program that presents the output of this
M-profiling result in a tabular report.
GTM>zprint ^tracereport
tracereport(gbl,label,rtn)
set gap=15
set $piece(x,".",gap*6)="" write x,!
write "Line #",?gap,"Count",?gap*2,"User Time",?gap*3,"System Time",?gap*4,"Total Time",?gap*5,"Elapsed Time",!
set $piece(x,".",gap*6)="" write x,!
for set gbl=$query(@gbl) quit:gbl="" do
. if ($length(@gbl,":")=5)&($qsubscript(gbl,1)=rtn)&($qsubscript(gbl,2)=label) do
.. set gap=15 set lineno=$qsubscript(gbl,3)
.. if lineno="" write label," total",?gap set zp=""
.. else write lineno,?gap set zp=label_"+"_lineno_"^"_rtn
.. for i=1:1:5 set gap=gap+15 write $piece(@gbl,":",i),?gap
.. write !
.. set maxlines=$qsubscript(gbl,3)
for i=0:1:maxlines do
. set zp=label_"+"_i_"^"_rtn
. write "Line #",i,": ",?9
. zprint @zp
GTM>do ^tracereport("^trc","order","profiling")
.........................................................................................
Line # Count User Time System Time Total Time Elapsed Time
.........................................................................................
order total 1 12001 8001 20002 25720
0 1 0 0 0 8
1 1 0 0 0 6
2 1 0 0 0 90
3 1 0 8001 8001 7160
4 1500 0 0 0 6319
5 1500 12001 0 12001 12069
6 1500 0 0 0 0
7 1 0 0 0 63
Line #0: order(y)
Line #1: new i,ordval
Line #2: set x="",i=0,y=y_"(x)",x=$order(@y)
Line #3: for quit:x="" do
Line #4: . set:i#2 ordval(i)=x
Line #5: . set x=$order(@y)
Line #6: . set i=i+1
Line #7: quit
This shows that order^profiling has an elapsed time of 25720 and the
maximum elapsed time was on line #5, which was executed 1500 times.
GTM>do ^tracereport("^trc","merge","profiling")
.........................................................................................
Line # Count User Time System Time Total Time Elapsed Time
.........................................................................................
merge total 1 8001 12000 20001 16231
0 1 0 0 0 5
1 1 0 0 0 4
2 1 0 0 0 4
3 1 8001 0 8001 8044
4 1 0 12000 12000 7992
5 1500 0 0 0 4
6 1 0 0 0 174
Line #0: merge(y)
Line #1: new i,merval
Line #2: set i=0,merval=0
Line #3: merge merval=@y
Line #4: for i=1:1:$order(merval(""),-1) do
Line #5: . kill:i#2 merval(i)
Line #6: quit
GTM>
This shows that merge^profiling has an elapsed time of 16231 and the
maximum elapsed time was on line #3, which was executed once.
Note that M-profiling results are reported for each line. While reporting
time for a line containing an invocation of a label, M-profiling excludes
the execution time of that label.
Here is an example:
GTM>do ^tracereport("^trc","qom","profiling")
.........................................................................................
Line # Count User Time System Time Total Time Elapsed Time
.........................................................................................
qom total 1 0 0 0 78
0 1 0 0 0 18
1 1 0 0 0 11
2 1 0 0 0 9
3 1 0 0 0 11
4 1 0 0 0 5
Line #0: qom(y)
Line #1: do query(y)
Line #2: do order(y)
Line #3: do merge(y)
Line #4: quit
Notice that the execution of do merge(y) reports an Elapsed Time of 9
whereas merge^profiling reported an Elapsed Time of 1149.
You can write programs like tracereport.m to interpret the results of the
M-profiling data and also use them to analyze your code execution path
based on your unique requirements.
view "trace":1: "<gbl>" and view "trace":0: "<gbl>" commands enable and
disable M-profiling.
To perform entryref-specific M-profiling without modifying the source
program, use ZBREAK. For example, to perform M-profiling of the entryref
merge^profiling, remove VIEW "TRACE" commands from profiling.m and then
execute the following commands:
GTM>ZBREAK merge^profiling:"view ""TRACE"":1:""^mtrc"" write ""Trace"""
GTM>do ^profiling
Trace
GTM>view "TRACE":0:"^mtrc"
GTM>zwrite ^mtrc
^mtrc("*CHILDREN")="0:0:0"
^mtrc("*RUN")="132008:52003:184011"
^mtrc("GTM$DMOD","^")="1:0:0:0:4"
^mtrc("profiling","merge")="1:8001:0:8001:13450"
^mtrc("profiling","merge",1)="1:0:0:0:6"
^mtrc("profiling","merge",2)="1:0:0:0:5"
^mtrc("profiling","merge",3)="1:8001:0:8001:6188"
^mtrc("profiling","merge",4)="1:0:0:0:7149"
^mtrc("profiling","merge",4,"FOR_LOOP",1)=1500
^mtrc("profiling","merge",5)="1500:0:0:0:4"
^mtrc("profiling","merge",6)="1:0:0:0:63"
^mtrc("profiling","profiling")="1:0:0:0:9"
^mtrc("profiling","profiling",8)="1:0:0:0:4"
^mtrc("profiling","qom")="1:0:0:0:9"
^mtrc("profiling","qom",4)="1:0:0:0:4"
Example:
If prof.m is:
prof;
set start=1
set finish=1000
view "TRACE":1:"^trc"
kill cycle S max=$$docycle(start,finish,"cycle")
view "TRACE":0:"^trc"
zwrite ^trc
quit
;
docycle(first,last,var)
new i,currpath,current,maxcycle,n
set maxcycle=1
for current=first:1:last do cyclehelper
quit maxcycle
;
cyclehelper
set n=current
kill currpath
for i=0:1 quit:$data(@var@(n))!(1=n) D
. set currpath(i)=n
. do iterate
if 0<i do
. if 1=n set i=i+1
. else set i=i+@var@(n)
. do updatemax
. set n="" for set n=$O(currpath(n)) Q:""=n S @var@(currpath(n))=i-n
Q
;
iterate
if 0=(n#2) set n=n/2
else set n=3*n+1
quit
;
updatemax
set:i>maxcycle maxcycle=i
quit
;
On executing prof, the output looks like the following (times in the
example were chosen for clarity of illustration and are not typical).
^trc("*CHILDREN")="0:0:0"
^trc("*RUN")="224014:12000:236014"
^trc("prof","cyclehelper")="1000:200013:0:200013:206318"
^trc("prof","cyclehelper",1)="1000:12001:0:12001:3202"
^trc("prof","cyclehelper",2)="1000:0:0:0:3766"
^trc("prof","cyclehelper",3)="1000:64004:0:64004:94215"
^trc("prof","cyclehelper",3,"FOR_LOOP",1)=3227
^trc("prof","cyclehelper",4)="2227:0:0:0:9864"
^trc("prof","cyclehelper",5)="2227:0:0:0:7672"
^trc("prof","cyclehelper",6)="1000:12000:0:12000:3758"
^trc("prof","cyclehelper",7)="432:0:0:0:1520"
^trc("prof","cyclehelper",8)="432:8000:0:8000:11003"
^trc("prof","cyclehelper",9)="432:0:0:0:3298"
^trc("prof","cyclehelper",10)="432:104008:0:104008:61564"
^trc("prof","cyclehelper",10,"FOR_LOOP",1)=2659
^trc("prof","cyclehelper",11)="1000:0:0:0:3424"
^trc("prof","docycle")="1:12001:0:12001:4886"
^trc("prof","docycle",0)="1:0:0:0:83"
^trc("prof","docycle",1)="1:0:0:0:36"
^trc("prof","docycle",2)="1:0:0:0:4"
^trc("prof","docycle",3)="1:12001:0:12001:4706"
^trc("prof","docycle",3,"FOR_LOOP",1)=1000
^trc("prof","docycle",4)="1:0:0:0:1718579845"
^trc("prof","iterate")="2227:12000:12000:24000:30240"
^trc("prof","iterate",1)="2227:0:0:0:8271"
^trc("prof","iterate",2)="2227:12000:0:12000:7727"
^trc("prof","iterate",3)="2227:0:0:0:7658"
^trc("prof","prof",4)="1:0:0:0:22"
^trc("prof","prof",5)="1:0:0:0:8"
^trc("prof","updatemax")="432:0:0:0:4276"
^trc("prof","updatemax",1)="432:0:0:0:1465"
^trc("prof","updatemax",2)="432:0:0:0:1496"
Example:
If fortypes.m is:
fortypes;
new i,j,k,v
set k=1
view "TRACE":1:"^trc"
for i=1:1:3 set v=i
for i=1:1 set v=0 quit:i=3
for i=1,2:1:4,6 set v=0
for i=1:1,2 set v=0 quit:i=3
for i=1:1:2 for j=1:1:3 set v=0
for i=1:1:2
. for j=1:1:1 do
.. set v=0
set j=5 for i=1:1:j do
. set j=(j-1)
for i=1:1:2 for j=1:1:3 do
. set v=0
for i=1:1:2 do
. for j=1:1:3 set v=0
for i=1:1:2 do
. for j=1:1:3 do
.. set v=0
for i="foo","bar",1:1 set v=0 quit:i=3
for set k=k+1 quit:k=3
for i=1:1:3 for j=1:1:(3-i) set v=0
for i=1:1:3 for j=1:1:(3-i) for k=1:1:(j+1) set v=0
set k=3 view "TRACE":0:"^trc"
zwrite ^trc
quit
On executing fortypes, the output looks something like the following:
^trc("*CHILDREN")="4000:0:4000"
^trc("*RUN")="468029:48003:516032"
^trc("fortypes","fortypes",5)="1:0:0:0:9"
^trc("fortypes","fortypes",5,"FOR_LOOP",1)=3
^trc("fortypes","fortypes",7)="1:0:0:0:6"
^trc("fortypes","fortypes",7,"FOR_LOOP",1)=3
^trc("fortypes","fortypes",9)="1:0:0:0:6"
^trc("fortypes","fortypes",9,"FOR_LOOP",1)=5
^trc("fortypes","fortypes",11)="1:0:0:0:6"
^trc("fortypes","fortypes",11,"FOR_LOOP",1)=3
^trc("fortypes","fortypes",13)="1:0:0:0:8"
^trc("fortypes","fortypes",13,"FOR_LOOP",1)=2
^trc("fortypes","fortypes",13,"FOR_LOOP",2)=6
^trc("fortypes","fortypes",15)="1:0:0:0:4"
^trc("fortypes","fortypes",15,"FOR_LOOP",1)=2
^trc("fortypes","fortypes",19)="1:0:0:0:26"
^trc("fortypes","fortypes",19,"FOR_LOOP",1)=5
^trc("fortypes","fortypes",20)="5:0:0:0:4"
^trc("fortypes","fortypes",22)="1:0:0:0:27"
^trc("fortypes","fortypes",22,"FOR_LOOP",1)=2
^trc("fortypes","fortypes",22,"FOR_LOOP",2)=6
^trc("fortypes","fortypes",23)="6:0:0:0:3"
^trc("fortypes","fortypes",25)="1:0:0:0:11"
^trc("fortypes","fortypes",25,"FOR_LOOP",1)=2
^trc("fortypes","fortypes",26)="2:0:0:0:6"
^trc("fortypes","fortypes",26,"FOR_LOOP",1)=6
^trc("fortypes","fortypes",28)="1:0:0:0:8"
^trc("fortypes","fortypes",28,"FOR_LOOP",1)=2
^trc("fortypes","fortypes",29)="2:0:0:0:26"
^trc("fortypes","fortypes",29,"FOR_LOOP",1)=6
^trc("fortypes","fortypes",30)="6:0:0:0:4"
^trc("fortypes","fortypes",32)="1:0:0:0:8"
^trc("fortypes","fortypes",32,"FOR_LOOP",1)=5
^trc("fortypes","fortypes",34)="1:0:0:0:5"
^trc("fortypes","fortypes",34,"FOR_LOOP",1)=2
^trc("fortypes","fortypes",36)="1:0:0:0:8"
^trc("fortypes","fortypes",36,"FOR_LOOP",1)=3
^trc("fortypes","fortypes",36,"FOR_LOOP",2)=3
^trc("fortypes","fortypes",38)="1:0:0:0:14"
^trc("fortypes","fortypes",38,"FOR_LOOP",1)=3
^trc("fortypes","fortypes",38,"FOR_LOOP",2)=3
^trc("fortypes","fortypes",38,"FOR_LOOP",3)=7
4 ZDATE_FORM
ZDATE_FORM
Determines whether four digit year code is active for $ZDATE() function.
GT.M defaults to zero (0), that is, two digit output.
If no value is given with the VIEW command, it turns four digit code on.
It is equivalent to the intrinsic special variable $ZDATEFORM. Use
$ZDATEFORM to set this VIEW keyword. Also, logical name environment
variable gtm_zdate_form may be used to set the initial value to this
factor.
3 Examples
Examples
Example:
GTM>Kill A
GTM>View "NOUNDEF"
GTM>Write A,?10,$L(A)
0
GTM>
This demonstrates how a VIEW that specifies NOUNDEF prevents UNDEFined
errors.
Example 2:
GTM>ZLink "NOSENSE"
%GTM-E-LABELMISSING Label referenced but
not defined:lab
%GTM-I-SRCNAM in source module /home/gtmuser1/.fis-gtm/V5.4-002B_x86/r/
NOSENSE.m
GTM>ZPrint ^NOSENSE
NOSENSE;
Do lab
Quit
LAB Write !,"THIS IS NOSENSE"
Quit
GTM>View "LABELS":"UPPER"
GTM>ZLink "NOSENSE.m"
GTM>Do ^NOSENSE
THIS IS NOSENSE
GTM>
This demonstrates use of VIEW "LABELS" to make label handling case
insensitive. Notice that the routine was ZLINKed with an extension of .m
to force a recompile and ensure that the object code and the run-time
handling of labels is the same.
2 Write
Write
The WRITE command transfers a character stream specified by its arguments
to the current device.
The format of the WRITE command is:
W[RITE][:tvexpr] expr|*intexpr|fcc[,...]
2 Xecute
Xecute
The XECUTE command makes an entry in the GT.M invocation stack and
executes the argument as GT.M code.
The format of the XECUTE command is:
X[ECUTE]:tvexpr expr[:tvexpr][,...]
3 Examples
Examples
Example:
GTM>Xecute "Write ""HELLO"""
HELLO
GTM>
This demonstrates a simple use of Xecute.
Example:
Set x="" For Set x=$Order(^%x(x)) Quit:x="" Xecute x
This $ORDER() loop XECUTEs code out of the first level of the global array
^%x. Note that, in most cases, having the code in a GT.M source file, for
example TMPX.m, and using a Do ^TMPX improves efficiency.
2 ZAllocate
ZAllocate
The ZALLOCATE command reserves the specified name without releasing
previously reserved names. Other GT.M processes cannot reserve the
ZALLOCATEd name with a ZALLOCATE or LOCK command.
The ZALLOCATE command provides compatibility with some other GT.M
implementations. The M Development Committee chose to add the + and -
delimiters to the LOCK command (incremental locking) rather than adopt the
ZALLOCATE and ZDEALLOCATE approach. Therefore, when a design requires an
incremental lock mechanism, LOCK +/- has the advantage over ZALLOCATE /
ZDEALLOCATE of being part of the M standard. LOCK +/- also has the
advantage of working symmetrically when routines using LOCKs are nested.
That is, a ZALLOCATE command issued by a process for a named resource
already ZALLOCATEd by that process results in no change of state. This
means that routines that do ZALLOCATE followed by a ZDEALLOCATE on a named
resource that is already ZALLOCATEd by the same process (at routine entry
time), will end up ZDEALLOCATEing the named resource (which might not be
desired). On the other hand, a LOCK + command issued by a process for a
named resource already LOCKed by that process causes the LEVEL of the LOCK
to be incremented (as seen in a ZSHOW "L" output). Every LOCK - command on
that named resource causes the LEVEL to be decremented. When the LEVEL
becomes 0, the named resource is no longer LOCKed.
The format of the ZALLOCATE command is:
ZA[LLOCATE][:tvexpr] [(]nref[,...][)][:intexpr][,...]
3 Examples
Examples
Examples:
ZAllocate A
ZAllocate ^A
ZAllocate ^A(1)
ZAllocate (^B("smith"),^C("jones"))
ZAllocate @A
The first command ZALLOCATEs A; the second, ^A; the third, ^A(1) and the
fourth, both ^B("smith") and ^C("jones") simultaneously. The last command
ZALLOCATEs the resources named by the value of the variable A.
Example:
ZAllocate A,^B,@C
ZALLOCATE (A,B,C)
If ZALLOCATE arguments are enclosed in parentheses, the command waits
until all names in the argument list become available before reserving any
of the names. For example, in the statement ZA (A,B,C), if the resource
named C is not available, ZALLOCATE waits until C becomes available before
reserving A and B. Using the format illustrated in the first line above,
can cause deadlocks because the resource names are reserved as they come
available.
When a process attempts to ZALLOCATE a name currently ZALLOCATEd or LOCKed
(with the LOCK command) by another process, the ZALLOCATEing process hangs
until the other process releases the name. In the event that names remain
unavailable for significant periods of time, timeouts allow the process
issuing a ZALLOCATE to regain program control.
Example:
ZAllocate ^D:5
This example specifies a timeout of five seconds. If GT.M reserves ^D
before the five seconds elapses, ZALLOCATE sets $TEST to TRUE. If GT.M
cannot reserve ^D within the five second timeout, ZALLOCATE sets $TEST to
FALSE.
At the time of ZALLOCATEing a name, no names previously reserved with
ZALLOCATE or the LOCK command are released (similarly, LOCKing a name does
not release names that have been ZALLOCATEd). For example, after
ZALLOCATEing A and LOCKing B, LOCKing B does not release A, and
ZALLOCATEing C does not release A or B.
ZDEALLOCATE releases ZALLOCATED resource names. The ZDEALLOCATE command
can only release previously ZALLOCATEd (not LOCKed) names.
Resource name arguments for LOCKs and ZALLOCATEs intersect. That is, if
one process holds a LOCK or ZALLOCATE, another process can neither LOCK
nor ZALLOCATE any name falling in the hierarchy of the resource name held
by the first process. When a process holds a LOCK or ZALLOCATE, that same
process may also LOCK or ZALLOCATE resource names falling in the hierarchy
of the currently held resource name. When a single process holds both
LOCKs and ZALLOCATEs, a LOCK does not release the ZALLOCATEd resource(s)
and a ZDEALLOCATE does not release the LOCKed resource(s).
Example:
Lock ^AR(PNT)
.
.
.
ZAllocate ^AR(PNT,SUB)
.
.
.
Lock ^TOT(TDT)
.
.
ZDEALLOCATE ^AR(PNT,SUB)
2 ZBreak
ZBreak
The ZBREAK command sets or clears routine breakpoints during debugging.
The format of the ZBREAK command is:
ZB[REAK][:tvexpr] [-]entryref[:[expr][:intexpr]][,...]
3 Examples
Examples
Example:
GTM>ZPRint ^ZBTEST
ZBTEST;
Do SUB
Quit
SUB Write !,"This is ZBTEST"
Quit
GTM>ZBREAK SUB^ZBTEST
GTM>Do ^ZBTEST
%GTM-I-BREAKZBA, Break instruction encountered during ZBREAK action
At M source location SUB^ZBTEST
GTM>ZSHOW "B"
SUB^ZBTEST
This inserts a ZBREAK with a default action at SUB^ZBTEST. After GT.M
encounters the BREAK, the ZSHOW "B" displays this as the only ZBREAK in
the image.
Example:
GTM>ZBREAK -*
GTM>ZGOTO
GTM>ZBREAK SUB^ZBTEST:"W !,""Trace"""
GTM>Do ^ZBTEST
Trace
This is ZBTEST
GTM>
This removes all existing ZBREAKs with a ZBREAK -*. Note that it is not
necessary to remove ZBREAKs before modifying them. It also clears the
process invocation stack with an argumentless ZGOTO. Then it uses a ZBREAK
to insert a trace-point. Every time GT.M executes the line to where ZBREAK
has established a trace-point, it performs the specified action without
entering Direct Mode.
Example:
ZBreak PRINT^TIME::5
This BREAKs execution at line PRINT in routine just before the fifth time
the line is executed.
Example:
ZBREAK PRINT^TIME:"WRITE AVE BREAK":3
This inserts a ZBREAK action of WRITE AVE and BREAK before the third
execution of PRINT^TIME.
2 ZCOMpile
ZCOMpile
The ZCOMPILE command invokes the GT.M compiler from within the GT.M
run-time environment.
Within GT.M itself, ZCOMPILE provides the functionality of the mumps
command, except for mumps -direct.
The format of the ZCOMPILE command is:
ZCOM[PILE][:tvexpr] expr[,...]
The $ZCSTATUS intrinsic special variable holds the value of the status
code for the compilation performed by a ZCOMPILE command.
3 Examples
Examples
Examples:
ZCOMPILE "EXAMPLE'.m"
This compiles EXAMPLE.m in the current working directory.
Example:
ZCOMPILE "-list A*.m"
This compiles all files starting with a [capital] A and an extension of .m
in the current working directory and produces corresponding listing files
for each source / object.
2 ZContinue
ZContinue
The ZCONTINUE command continues routine execution after a BREAK command or
a <CTRL-C>.
The format of the ZCONTINUE command is:
ZC[ONTINUE][:tvexpr]
2 ZDeallocate
ZDeallocate
The ZDEALLOCATE command releases a specified resource name or names
previously reserved by the ZALLOCATE command. The ZDEALLOCATE command
releases only the specified name(s) without releasing other names
previously reserved with the ZALLOCATE or LOCK command.
The ZDEALLOCATE command provides compatibility with some other GT.M
implementations. The M Development Committee choose to add the + and -
delimiters to the LOCK command rather than adopt the ZALLOCATE and
ZDEALLOCATE approach. Therefore, when a design requires an incremental
lock mechanism, LOCK +/- has the advantage of being part of the M
standard. LOCK +/- also has the advantage of working symmetrically when
routines using LOCKs are nested.
The format of the ZDEALLOCATE command is:
ZD[EALLOCATE][:tvexpr] [nref[,...]]
3 Examples
Examples
Example:
2 ZEDit
ZEDit
The ZEDIT command invokes the editor specified by the EDITOR environment
variable for GT.M and opens the specified file for editing. If the EDITOR
environment variable is undefined, ZEDIT tries to invoke the UNIX vi
editor.
By default, ZEDIT puts a new file into the first source directory in
$ZROUTINES. You can specify a file path explicitly in the argument to the
ZEDIT command, for example: the current working directory:
ZEDIT "./file"
The format of the ZEDIT command is:
ZED[IT][:tvexpr] [expr[,...]]
When the argument to a ZEDIT includes a file or path name, $ZSOURCE
maintains that as a default for ZEDIT and ZLINK.
3 Examples
Examples
Example:
GTM>ZEDIT "BAL"
This invokes the editor for a file with a name of BAL and an extension of
.m. Notice that BAL is a string literal.
Example:
GTM>Set prog="BAL"
GTM>ZEDit prog
This is similar to the first example except that it uses a variable
argument rather than a string literal.
Example:
GTM>zedit ".login"
This invokes the editor for a file with the name .login. Notice that in
this case the file is not a GT.M file, since .login starts with a period,
and therefore, cannot be a GT.M file.
2 ZGoto
ZGoto
The ZGOTO command transfers control to various levels in the GT.M
invocation stack. It also can transfer control from one part of the
routine to another or from one routine to another using the specified
entryref.
The format of the ZGOTO command is:
ZG[OTO][:tvexpr] [[intexpr][:entryref[:tvexpr]],...]
3 Examples
Examples
Example:
GTM>ZGOTO
GTM>ZSHow
+1^GTM$DMOD (Direct mode)
GTM>
This uses ZGOTO to clear all levels of the GT.M invocation stack. ZSHOW
with no arguments displays the stack.
Example:
SET $ZTRAP="ZGOTO "_$ZLEVEL_":^ERROR"
This SETs $ZTRAP to contain a ZGOTO, so if an error causes GT.M to XECUTE
$ZTRAP, the routine ERROR executes at the same level as the SET command
shown in the example.
2 ZHALT
ZHALT
The ZHALT command stops program execution and causes GT.M to return
control to the invoking environment/program with a return code.
The format of the ZHALT command is:
ZHALT[:tvexpr] [intexpr]
3 Examples
Examples
Example:
GTM>zhalt 230
$ echo $?
230
Example:
GTM>zhalt 257
$ echo $?
1
2 ZHelp
ZHelp
The ZHELP command accesses the help information from the GTM help library
or from any help library specified in the command argument.
The format of the ZHELP command is:
ZH[ELP][:tvexpr] [expr1[:expr2],...]
3 Examples
Examples
Example:
GTM>zhelp "func $data"
This lists the help for function $DATA, which is a subtopic of functions
topic.
Example:
GTM>zhelp
This uses ZHELP to list all the keywords in the help library.
Example:
GTM>zhelp "ZSHOW"
This lists the help for command ZSHOW.
2 ZLink
ZLink
The ZLINK command adds an executable GT.M routine to the current process
if the current process does not contain a copy of a routine. If the
current process contains a copy of a routine and the routine is not
active, the ZLINK command replaces the current routine process with a
"new" version. If necessary, the ZLINK command compiles the routine prior
to integrating it with the process.
With VIEW "LINK":"RECURSIVE" specified or by starting the process with the
environment variable gtm_link set to "RECURSIVE", the ZLINK command adds
an executable routine even when a routine with the same name is active and
available in the current stack. When a process links a routine with the
same name as an existing routine, future calls use the new routine. Prior
versions of that routine referenced by the stack remain tied to the stack
until they QUIT, at which point they become inaccessible. This provides a
mechanism to patch long-running processes.
**Important**
An active routine is displayed with $STACK() or ZSHOW "S" of the M virtual
stack. By default, an attempt to replace an active routine results in a
run-time error . To replace an active routine with a new version, either
use VIEW "LINK":"RECURSIVE" or remove the active routine from the stack
using ZGOTO or the appropriate number of QUITs and then execute the ZLINK
command.
The format of the ZLINK command is:
ZL[INK][:tvexpr] [expr1[:expr2][,...]]
3 ZLINK_Compilation
ZLINK Compilation
If ZLINK compiles a routine and the -OBJECT= qualifier does not redirect
the output, it places the resulting object file in the directory indicated
by the search criteria. ZLINK incorporates the new object file into the
image, regardless of its directory placement.
If the command does not specify compile qualifiers (with expr2) and
$ZCOMPILE is null, GT.M uses the default M command qualifiers, -ignore,
-labels=lower, -nolist, and -object.
3 Examples
Examples
Example:
GTM>ZLINK "test"
If ZLINK finds test.m or test.o, it adds the routine test to the current
image. If ZLINK does not find test.o, or finds that test.o is older than
test.m, GT.M compiles test.m to produce a new test.o, and adds the
contents of the new object file to the image. This example assumes "test"
is not on the current M stack - if it is on the stack, GT.M gives an
error.
Example:
GTM>zlink "test.m":"-noobject -list"
This compiles the routine "test" and produces a listing but no object
file. Because the example produces no object file, it must locate an
existing object file (which might be the same as any copy in the current
image); if there is noexisting object file, GT.M produces an error. While
this example shows the use of compilation qualifiers with ZLINK, a
-noobject -list compilation might better be done with ZCOMPILE.
Example:
GTM>zlink "sockexamplemulti2"
%GTM-E-LOADRUNNING, Cannot ZLINK an active routine sockexamplemulti2
GTM>zshow "S"
sockexamplemulti2+12^sockexamplemulti2 (Direct mode)
GTM>view "LINK":"RECURSIVE"
GTM>zlink "sockexamplemulti2"
GTM>
This example demonstrates how VIEW "LINK":"RECURSIVE" command ZLINKs a
routine when its prior version is already there in the active M virtual
stack.
3 Auto-ZLINK
Auto-ZLINK
If a GT.M routine refers to a routine that is not linked in the process
memory, GT.M automatically attempts to ZLINK that routine. An auto-ZLINK
is functionally equivalent to an explicit ZLINK of a routine without a
specified directory or file extension.
The following GT.M commands and functions can initiate auto-ZLINKing:
* DO
* GOTO
* ZBREAK
* ZGOTO
* ZPRINT
* $TEXT()
GT.M auto-ZLINKs the routine if the following conditions are met:
* ZLINK can locate and process the routine file, as indicated in the
previous ZLINK Operation Summary table
* The name of the routine is the same as the name of the source file;
the only exception is that GT.M converts a leading percent sign (%) in
a file name to an underscore (_).
3 Auto-ZLINK_setup
Auto-ZLINK setup
This section describes the procedure to setup the field test grade
auto-relink functionality that is available in V6.2-000. Although V6.2-000
when used without auto-relink (i.e., without use of the ZRUPDATE command
or the special syntax in $ZROUTINES) is a generally available, production
grade release, use auto-relink only in development and test environments
where field test grade functionality is acceptable.
By suffixing one or more directory names in $ZROUTINES with a single
asterisk (*), processes can subscribe to updates of object files published
in those directories. At the invocation of DO, GOTO, or ZGOTO, extrinsic
functions, $TEXT(), or ZPRINT that specify an entryref which includes a
routine name (vs. a label without a routine name), mumps processes (and
mupip processes executing trigger logic) automatically relink
("auto-relink") and execute published new versions of routines.
o Label references (that is , without a routine name), whether direct or
through indirection, always refer to the current routine, and do not
invoke auto-relink logic.
o Use shell quoting rules when appending asterisks to directory names in
the gtmroutines environment variable - asterisks must be passed in to
GT.M, and not expanded by the shell.
o GT.M accepts but ignores asterisk suffixes to directory names on
32-bit Linux on x86 platforms, where it does not provide
auto-relinking.
The ZRUPDATE command publishes of new versions of routines to subscribers.
To remove routines, delete the object files and publish the names of the
deleted object files. Removal requires file names to be explicitly
specified, because patterns with wildcards cannot match deleted files.
If the path to a file is non-existent, the request is ignored except in
the case where one desires a currently shared object file (one that was
accessed before it was deleted) to no longer be shared. In V6.2-000, if
the process executing the ZRUPDATE does not have read permission to any
directory in the path to a file, ZRUPDATE ignores the request; FIS expect
to correct this in the production release.
To effect auto-relink, GT.M creates small temporary files in the directory
referred to by $gtm_linktmpdir (defaulting to $gtm_tmp, which in turn
defaults to /tmp, if unspecified). The names of these files are of the
form gtm-relinkctl-<md5sum> where <md5sum> is a hash of the realpath() to
an auto-relink directory. In the field test software, the permissions are
determined by the umask of the process creating a file. In the production
software, FIS intends for the group and permissions to match those for
shared resources as described in the section Shared Resources
Authorization Permissions in Appendix E (GT.M Security Philosophy) of the
UNIX Administration and Operations Guide. FIS recommends that all
processes that share a directory whose contents are subject to ZRUPDATE
use the same value for $gtm_linktmpdir so that all processes see update
notifications - with different values of $gtm_linktmpdir, a ZRUPDATE by a
process with one value of $gtm_linktmpdir would not be observed by a
process with a different value of that environment variable.
When a process that has subscribed to updates to routines in a directory
links to a routine from that directory, it maps the object file to its
address space, sharing the object code with other processes that are so
subscribed, and without requiring the object code to be placed in a shared
library. Processes that have not subscribed to updates link using
process-private heap space as they have in prior versions.
AIX has known architectural limitations to scalability when large numbers
of processes (thousands to tens of thousands) auto-relink large numbers of
routines (again thousands to tens of thousands of routines). In the
typical case where the number of dynamically modified routines is much
smaller than the total number of routines in an enterprise scale
application, a scalable way for large applications to use auto-relinking
on AIX is to place all routines in shared libraries, and define $ZROUTINES
with an auto-relink enabled patch directory preceding the shared library.
Scalability on HP-UX and Solaris is not known: FIS is not aware of any
inherent scalability issues other than those imposed by available hardware
resources when the product of the number of processes and the number of
auto-relinked remains well below the number of file descriptors made
available by the OS.
Changing $ZROUTINES currently causes all routines linked from
auto-relink-enabled directories in the process to be re-linked. FIS
intends for this to generate an error in the production release.
VIEW "RCTLDUMP" displays the created relinkctl files and the routines
looked for in their related directories. An entry in these files does not
mean that a given routine was found there. It merely means it was looked
for there and shows a cycle number (which ZRUPDATE bumps) whose change
indicates a new published version of the given object file. As it is a
diagnostic tool for the new feature, FIS may remove or modify this VIEW
option in subsequent releases.
3 ZLINK,_auto-ZLINK_and_Routine_Names
ZLINK, auto-ZLINK and Routine Names
In GT.M, the name of the source file determines the name of the GT.M
routine. The file name of the object file is not required to match the
name of the routine. Linking the object file makes the internal routine
name (derived from the source file) known to GT.M. This can lead to
potential confusion, however, since both ZLINK and auto-ZLINK use the name
of the object file to find the routine. When the object file name differs
from the name of the routine, auto-ZLINK generates a run-time error.
**Note**
Auto-ZLINK and ZLINK commands without a .m or .o file extension in their
argument determine the need to recompile based on whether the object file
was more recently modified than the source file using time in nanoseconds,
as provided by the underlying system call. Note that, although the format
of the file modification timestamps provides a nanosecond granularity,
many supported OSs currently update the file timestamps with an accuracy
of one second.
2 ZKill
ZKill
The ZKILL command KILLs the data value for a variable name without
affecting the nodes descended from that node.
The format of the ZKILL command is:
ZK[ILL][:tvexpr] glvn
2 ZMessage
ZMessage
The ZMESSAGE command raises an exception condition based on the specified
message code.
The format of the ZMESSAGE command is:
ZM[ESSAGE][:tvexpr] intexpr[:expr2][:...]
3 Examples
Examples
All of the following examples issue ZMESSAGE from Direct Mode where
exception conditions do not invoke $ZTRAP.
Example:
GTM>ZMessage 2
%SYSTEM-E-ENO2, No such file or directory
This ZMESSAGE does not specify substitution text and the message does not
include any substitution directives.
Example:
GTM>ZMESSAGE 150372994
%GTM-E-GVUNDEF, Global Variable undefined:
The message specified by this ZMESSAGE command includes a substitution
directive but the command does not supply any text.
Example:
GTM>ZMESSAGE 150373850:"x"
%GTM-E-GVUNDEF, Undefined local variable: x
This ZMESSAGE command supplies the substitution text for the message.
GT.M treats its own odd-numbered conditions as "successful." GT.M handles
successful conditions by displaying the associated message and continuing
execution. GT.M treats its own even-numbered conditions as failures. GT.M
handles failure conditions by storing the error information in $ZSTATUS
and XECUTEing $ETRAP or $ZTRAP In Direct Mode, GT.M only reports failure
conditions to the principal device and does not XECUTE $ETRAP or $ZTRAP or
set $ZSTATUS. System service errors do not follow the GT.M odd/even
pattern.
2 ZPrint
ZPrint
The ZPRINT command displays the source code lines selected by its
argument.
The format of the ZPRINT command is:
ZP[RINT][:tvexpr][entryref[:label[+intexpr]][,...]
Note that the routinename may only appear before the colon (:) delimiter.
The integer expression offsets may be positive or negative, but they must
always be delimited by a plus sign (+).
3 Examples
Examples
Example:
GTM>ZPRINT X^RTN
This example displays the line beginning with the label X in the routine
RTN.
Example:
GTM>ZPRINT X^RTN:X+5
GTM>ZPRINT X+-5^RTN:X
GTM>ZPRINT X^RTN:X+-5^RTN
The first line displays the line beginning with the label X and the next 5
lines in routine RTN. The second line displays the 5 lines preceding label
X in the same routine and the line beginning with label X. The third line
generates a run-time error because the routine name must appear only
before the colon in the argument.
Example:
GTM>zprint ^A#1#
do ^test1
do stop^test2
GTM>
This command displays the trigger code for trigger name A#1#.
2 ZRUPDATE
ZRUPDATE
Publishes the new versions of routines to subscribers. THe format of the
ZRUPDATE command is:
ZRUP[DATE][:tvexpr] expr [,...]
o The optional truth-valued expression immediately following the command
is a command postconditional that controls whether or not GT.M
executes the command.
o expr contains a object file names, with or without wildcards, for
which ZRUPDATE attempts to publish the new version of routines to
subscribers.
o To remove routines, delete the object files and publish the names of
the deleted object files. Removal requires file names to be explicitly
specified, because patterns with wildcards cannot match deleted files.
o If the path to a file is non-existent, the request is ignored except
in the case where one desires a currently shared object file (one that
was accessed before it was deleted) to no longer be shared. In
V6.2-000, if the process executing the ZRUPDATE does not have read
permission to any directory in the path to a file, ZRUPDATE ignores
the request; FIS expects to correct this in the production release.
o To effect auto-relink, GT.M creates small temporary files in the
directory referred to by $gtm_linktmpdir (defaulting to $gtm_tmp,
which in turn defaults to /tmp, if unspecified). The names of these
files are of the form gtm-relinkctl<md5sum> where <md5sum> is a hash
of the realpath() to an auto-relink directory. In the field test
software, the permissions are determined by the umask of the process
creating a file. In the production software, FIS intends for the group
and permissions to match those for shared resources as described in
the section Shared Resources Authorization Permissions in Appendix E
(GT.M Security Philosophy) of the UNIX Administration and Operations
Guide. FIS recommends that all processes that share a directory whose
contents are subject to ZRUPDATE use the same value for
$gtm_linktmpdir so that all processes see update notifications - with
different values of $gtm_linktmpdir, a ZRUPDATE by a process with one
value of $gtm_linktmpdir would not be observed by a process with a
different value of that environment variable.
2 ZSHow
ZSHow
The ZSHOW command displays information about the current GT.M environment.
The format of the ZSHOW command is:
ZSH[OW][:tvexpr][expr[:glvn][,...]]
3 ZSHOW_Information_Codes
ZSHOW Information Codes
A ZSHOW argument is an expression containing codes selecting one or more
types of information.
B: displays active ZBREAK breakpoints
D: displays device information
G: displays the access statistics for global variables and access to
database file since process startup
I: displays the current values of all intrinsic special variables
L: displays GT.M LOCKs and ZALLOCATEs held by the process
R: displays the GT.M invocation stack and an MD5 checksum of M source code
for each routine on the stack.
S: displays the GT.M invocation stack
V: displays local and alias variables
* displays all possible types of ZSHOW information
Codes may be upper- or lower-case. Invalid codes produce a run-time error.
Multiple occurrences of the same code in one ZSHOW argument only produce
one output instance of the corresponding information. The order of the
first appearance of the codes in the argument determines the order of the
corresponding output instances.
If you are using a local variable destination and place another code ahead
of "V", the effect is to have the results of the earlier code also appear
in the results of the "V" code.
If the wildcard (*) occurs in the list, ZSHOW uses the default order
(ZSHOW "IVBDLGR" ):
If G occurs in the list, the statistics are displayed in the following
order in a comma-separated list where each item has its mnemonic followed
by a colon and a counter. GT.M maintains the counter in DECIMAL. Each
counter has 8-byte (can get as high as 2**64). If these counters exceed 18
decimal digits (somewhere between 2**59 and 2**60), which is the current
GT.M numeric representation precision threshold, their use in arithmetic
expressions in GT.M results in loss of precision. The mnemonics are:
SET : # of SET operations (TP and non-TP)
KIL : # of KILl operations (kill as well as zwithdraw, TP and non-TP)
GET : # of GET operations (TP and non-TP)
DTA : # of DaTA operations (TP and non-TP)
ORD : # of $ORDer() operations (TP and non-TP). The count of $Order(xxx,1) operations are reported under this item.
ZPR : # of $ZPRevious() (reverse order) operations (TP and non-TP). The count of $Order(xxx,-1) operations are reported under this item.
QRY : # of $QueRY() operations (TP and non-TP)
LKS : # of LocK calls (mapped to this db) that Succeeded
LKF : # of LocK calls (mapped to this db) that Failed
CTN : Current Transaction Number of the database for the last committed read-write transaction (TP and non-TP)
DRD : # of Disk ReaDs from the database file (TP and non-TP, committed and rolled-back).This does not include reads that are satisfied by buffered globals for databases that use the BG (Buffered Global) access method. GT.M always reports 0 for databases that use the MM (memory-mapped) access method as this has no real meaning in that mode.
DWT : # of Disk WriTes to the database file (TP and non-TP, committed and rolled-back). This does not include writes that are satisfied by buffered globals for databases that use the BG (Buffered Global) access method. GT.M always reports 0 for databases that use the MM (memory-mapped) access method as this has no real meaning in that mode.
NTW : # of Non-TP committed Transactions that were read-Write on this database
NTR : # of Non-TP committed Transactions that were Read-only on this database
NBW : # of Non-TP committed transaction induced Block Writes on this database
NBR : # of Non-TP committed transaction induced Block Reads on this database
NR0 : # of Non-TP transaction Restarts at try 0
NR1 : # of Non-TP transaction Restarts at try 1
NR2 : # of Non-TP transaction Restarts at try 2
NR3 : # of Non-TP transaction Restarts at try 3
TTW : # of TP committed Transactions that were read-Write on this database
TTR : # of TP committed Transactions that were Read-only on this database
TRB : # of TP read-only or read-write transactions that got Rolled Back (incremental rollbacks are not counted)
TBW : # of TP transaction induced Block Writes on this database
TBR : # of TP transaction induced Block Reads on this database
TR0 : # of TP transaction Restarts at try 0 (counted for all regions participating in restarting TP transaction)
TR1 : # of TP transaction Restarts at try 1 (counted for all regions participating in restarting TP transaction)
TR2 : # of TP transaction Restarts at try 2 (counted for all regions participating in restarting TP transaction)
TR3 : # of TP transaction Restarts at try 3 (counted for all regions participating in restarting TP transaction)
TR4 : # of TP transaction Restarts at try 4 and above (restart counted for all regions participating in restarting TP transaction)
TC0 : # of TP transaction Conflicts at try 0 (counted only for that region which caused the TP transaction restart)
TC1 : # of TP transaction Conflicts at try 1 (counted only for that region which caused the TP transaction restart)
TC2 : # of TP transaction Conflicts at try 2 (counted only for that region which caused the TP transaction restart)
TC3 : # of TP transaction Conflicts at try 3 (counted only for that region which caused the TP transaction restart)
TC4 : # of TP transaction Conflicts at try 4 and above (counted only for that region which caused the TP transaction restart)
DFL : # of times a process flushes the entire set of dirty database global buffers in shared memory to disk.
DFS : # of times a process does an fsync of the database file. For example: a) after writing an epoch journal record, b) as part of database file extension c) during database rundown d) as part of mupip reorg -truncate etc.
JFL : # of times a process flushes all dirty journal buffers in shared memory to disk. For example: when switching journal files etc.
JFS : # of times a process does an fsync of the journal file. For example: when writing an epoch record, switching a journal file etc.
JBB : # of bytes written to the journal buffer in shared memory.
JFB : # of bytes written to the journal file on disk. For performance reasons, GT.M always aligns the beginning of these writes to file system block size boundaries. On Unix, JFB counts all bytes including those needed for alignment in order to reflect the actual IO load on the journal file. Since the bytes required to achieve alignment may have already been counted as part of the previous JFB, processes may write the same bytes more than once, causing the JFB counter to typically be higher than JBB.
JFW : # of times a process invokes a write system call for a journal file.
JRL : # of logical journal records (e.g. SET, KILL etc.)
JRP : # of PBLK and AIMG journal records written to the journal file (these records are seen only in a -detail journal extract)
JRE : # of regular EPOCH journal records written to the journal file (only seen in a -detail journal extract); these are written every time an epoch-interval boundary is crossed while processing updates
JRI : # of idle EPOCH journal records written to the journal file (only seen in a -detail journal extract); these are written when a burst of updates is followed by an idle period, around 5 seconds of no updates after the database flush timer has flushed all dirty global buffers to the database file on disk
JRO : # of all journal records other than logical, PBLK, AIMG and EPOCH records written to the journal file (for example, PINI, PFIN, and so on.)
JEX : # of times a process extends the journal file
DEX : # of times a process extends the database file
[NT]B[WR] mnemonics are satisfied by either disk access or, for databases that use the BG (buffered global) access method, global buffers in shared memory.
3 Examples
Examples
Example:
GTM>ZSHOW "db"
This command displays all devices with deviceparameters reflecting their
current characteristics followed by any current ZBREAK locations with
their corresponding actions.
Example:
GTM>ZSHOW "dbd"
This command displays the same output as the previous example.
Example:
GTM>ZSHOW "ax"
This command generates a run-time error.
Example:
LAB1 DO LAB2
Quit
LAB2 Do LAB3
Quit
LAB3 ZSHow
Quit
Produces the results:
LAB3^RTN
LAB2^RTN
LAB1^RTN
Example:
GTM>ZSHOW "G"
For process that has access to two database files produces results like
the following:
GLD:*,REG:*,SET:205,KIL:0,GET:1,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,CTN:0,DRD:9,DWT:15,
NTW:203,NTR:4,NBW:212,NBR:414,NR0:0,NR1:0,NR2:0,NR3:0,TTW:1,TTR:0,TRB:0,TBW:2,TBR:6,
TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
GLD:/home/gtmuser1/.fis-gtm/V5.4-002B_x86/g/mumps.gld,REG:DEFAULT,SET:205,KIL:0,GET:1,
DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,CTN:411,DRD:9,DWT:15,NTW:2
03,NTR:4,NBW:212,NBR:414,NR0:0,NR1:0,NR2:0,NR3:0,TTW:1,TTR:0,TRB:0,TBW:2,TBR:6,TR0:0,
TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
GLD:/tmp/tst/test.gld,REG:DEFAULT,SET:205,KIL:0,GET:1,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,
CTN:411,DRD:9,DWT:15,NTW:203,NTR:4,NBW:212,NBR:414,NR0:0,NR1:0,NR2:0,NR3:0,TTW:1,TTR:0,TRB:0,
TBW:2,TBR:6,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
Example:
GTM>ZSHOW "G"
Assuming that a GT.M process uses the global directory "/tmp/x1.gld" and
opens two regions REG1 and REG2 corresponding to two database files, the
above command produces results like the following:
GLD:*,REG:*,SET:0,KIL:0,GET:0,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,CTN:0,DRD:0,DWT:0,NTW:0,
NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,NR3:0,TTW:0,TTR:0,TRB:0,
TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
GLD:/tmp/x1.gld,REG:REG1,SET:0,KIL:0,GET:0,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,CTN:0,DRD:0,
DWT:0,NTW:0,NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,NR3:0,TTW:0,
TTR:0,TRB:0,TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
GLD:/tmp/x1.gld,REG:REG2,SET:0,KIL:0,GET:0,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,LKF:0,CTN:0,DRD:0,
DWT:0,NTW:0,NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,NR3:0,TTW:0,
TTR:0,TRB:0,TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0
Example:
GTM>ZSHOW "G":zgbl
This example redirects the output of ZSHOW "G" into a local variable zgbl:
zgbl("G",0)="GLD:*,REG:*,SET:0,KIL:0,GET:0,DTA:0,ORD:0,
ZPR:0,QRY:0,LKS:0,LKF:0,CTN:0,DRD:0,DWT:0,NTW:0,NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,NR3:0,TTW:0,
TTR:0,TRB:0,TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0"
zgbl("G",1)="GLD:/tmp/x1.gld,REG:REG1,SET:0,KIL:0,GET:0,DTA:0,ORD:0,ZPR:0,QRY:0,
LKS:0,LKF:0,CTN:0,DRD:0,DWT:0,NTW:0,NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,
NR3:0,TTW:0,TTR:0,TRB:0,TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0"
zgbl("G",2)="GLD:/tmp/x1.gld,REG:REG2,SET:0,KIL:0,GET:0,DTA:0,ORD:0,ZPR:0,QRY:0,LKS:0,
LKF:0,CTN:0,DRD:0,DWT:0,NTW:0,NTR:0,NBW:0,NBR:0,NR0:0,NR1:0,NR2:0,
NR3:0,TTW:0,TTR:0,TRB:0,TBW:0,TBR:0,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0"
Example:
GTM>LOCK ^FAIL:10
GTM>lock (^SUCCESS1,^SUCCESS2)
GTM>zshow "L"
MLG:1,MLT:1
LOCK ^SUCCESS1 LEVEL=1
LOCK ^SUCCESS2 LEVEL=1
This output shows that a process locked ^SUCCESS1 and ^SUCCESS2 and
another the lock on ^FAIL failed due to time out.
Note that even though two lock resources ^SUCCESS1 and ^SUCCESS2 were
specified in the LOCK command that succeeded, GT.M increments the MLG
counter by only 1 because they are part of the same LOCK command. A ZSHOW
"L":var by the same process (redirecting the output of ZSHOW into a local
or global variable) would result in <var> holding the following contents.
var("L",0)="MLG:1,MLT:1"
var("L",1)="LOCK ^SUCCESS1 LEVEL=1"
var("L",2)="LOCK ^SUCCESS2 LEVEL=1"
Example:
GTM>ZSHOW "L":var
GTM>ZWRITE var
var("L",0)="MLG:1,MLT:1"
var("L",1)="LOCK ^SUCCESS1 LEVEL=1"
var("L",2)="LOCK ^SUCCESS2 LEVEL=1"
This example shows how ZSHOW "L" redirects it output into a local variable
var.
Example:
Suppose a process runs LOCK (^SUCCESS1,^SUCCESS2) which succeeds and a
LOCK +^FAIL:1 which times out due to another process holding that lock. A
ZSHOW "L" at this point displays the following output.
3 ZSHOW_Destination_Variables
ZSHOW Destination Variables
ZSHOW may specify an unsubscripted or subscripted global or local variable
name (glvn) into which ZSHOW places its output. If the argument does not
include a global or local variable name, ZSHOW directs its output to the
current device.
When ZSHOW directs its output to a variable, it adds two levels of
descendants to that variable. The first level subscript contains a
one-character string from the set of upper-case ZSHOW action codes,
identifying the type of information. ZSHOW implicitly KILLs all
descendants of the first level nodes. ZSHOW stores information elements at
the second level using ascending integers, starting at 1.
When a ZSHOW "V" directs its output to a local variable (lvn), the result
does not contain a copy of the descendants of the resulting "V" node.
Example:
GTM>Kill Set b(1,"two")="test" ZSHow "v":a ZWRite
a("V",1)="b(1,""two"")=""test"""
b(1,"two")="test"
GTM>
This ZSHow stores all local variables in the local variable a. Note that
ZSHOW does not replicate a("V") and a("V",1).
Example:
GTM>KILL SET a(1,"D",3,5)="stuff",a(1,"X",2)="",a(1)=1
GTM>ZSHow "d":a(1)
GTM>ZWRite
a(1)=1
a(1,"D",1)="/dev/pts/1 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
EDIT "
a(1,"X",2)=""
GTM>
This ZSHOW stores the current open device information under a(1). Notice
how the ZSHOW overlays the prior value of a(1,"D",3,5).
Example:
GTM>KILL ^ZSHOW
GTM>ZB -*,lab^rout ZSH "B":^ZSHOW
GTM>ZWRite ^ZSHOW
^ZSHOW("B",1)="LAB^ROUT"
GTM>
This ZSHOW stores the current ZBREAK information under the global variable
^ZSHOW.
2 ZSTep
ZSTep
The ZSTEP command provides the ability to control GT.M execution. When a
ZSTEP is issued from Direct Mode, execution continues to the beginning of
the next target line and then GT.M XECUTEs the ZSTEP action. The keyword
in the optional ZSTEP argument determines the class of eligible target
lines.
The format of the ZSTEP command is:
ZST[EP][:tvexpr] [keyword[:expr]][,...]
In Direct Mode, ZSTEP performs an implicit ZCONTINUE and therefore GT.M
ignores all commands on the Direct Mode command line after the ZSTEP.
The keyword arguments define the class of lines where ZSTEP next pauses
execution to XECUTE the ZSTEP action. When a ZSTEP command has multiple
arguments, it ignores all arguments except the last.
3 ZSTEP_Into
ZSTEP Into
ZSTEP INTO pauses at the beginning of the next line, regardless of
transfers of control. When the ZSTEPed line invokes another routine or a
subroutine in the current routine, ZSTEP INTO pauses at the first line of
code associated with the new GT.M stack level.
3 ZSTep_OUtof
ZSTep OUtof
ZSTEP OUTOF pauses at the beginning of the next line executed after an
explicit or implicit QUIT from the current GT.M invocation stack level. A
ZSTEP OUTOF does not pause at lines associated with the current GT.M stack
level or with levels invoked from the current level.
3 ZSTep_OVer
ZSTep OVer
ZSTEP OVER pauses at the beginning of the next line in the code associated
with either the current GT.M stack level or a previous GT.M stack level if
the ZSTEPed line contains an explicit or implicit QUIT from the current
level. A ZSTEP OVER does not pause at lines invoked from the current line
by DOs, XECUTEs or extrinsics.
3 ZSTEP_Actions
ZSTEP Actions
The optional action parameter of a ZSTEP must contain an expression
evaluating to valid GT.M code. By default, ZSTEP uses the value of $ZSTEP,
which defaults to "B" ("BREAK"), and enters Direct Mode. When a ZSTEP
command specifies an action, the process does not enter Direct Mode unless
the action explicitly includes a BREAK command.
3 ZSTEP_Interactions
ZSTEP Interactions
ZSTEP currently interacts with certain other elements in the GT.M
environment.
3 Use_of_ZSTEP
Use of ZSTEP
Use ZSTEP to incrementally execute a routine or series of routines.
Execute any GT.M command from Direct Mode at any ZSTEP pause. To resume
normal execution, use ZCONTINUE.
Note that ZSTEP arguments are keywords rather than expressions. They do
not allow indirection, and argument lists have no utility.
ZSTEP actions that include commands followed by a BREAK perform some
action before entering Direct Mode. ZSTEP actions that do not include a
BREAK perform the command action and continue execution. Use ZSTEP actions
that issue conditional BREAKs and subsequent ZSTEPs to do such things as
test for changes in the value of a variable.
3 Examples
Examples
Example:
GTM>ZSTEP INTO:"W ! ZP @$ZPOS W !"
This ZSTEP resumes execution of the current routine. At the beginning of
the next line executed, the ZSTEP action ZPRINTs the source code for that
line. Because the specified action does not contain a BREAK command,
execution continues to the next line and all subsequent lines in the
program flow.
Example:
GTM>Set curx=$get(x),zact="ZSTEP:curx=$get(x) INTO:zact Break:curx'=$get(x)"
GTM>ZSTEP INTO:zact
This sequence uses ZSTEP to invoke Direct Mode at the beginning of the
first line after the line that alters the value of x.
2 ZSYstem
ZSYstem
The ZSYSTEM command creates a child of the current process .
The format of the ZSYSTEM command is:
ZSY[STEM][:tvexpr] [expr][,...]]
3 Examples
Examples
Example:
GTM>ZSYSTEM "ls *.m"
This uses ZSYSTEM to fork a process that then performs the ls command with
*.m as an argument to ls. Once the command completes, the forked process
terminates.
Example:
GTM>ZSYSTEM
$
This ZSYSTEM has no argument so the forked process prompts for input.
2 ZTCommit
ZTCommit
The ZTCOMMIT command marks the end of a logical transaction within a GT.M
program. ZTCOMMIT used with ZTSTART "fences" transactions (that is, marks
the end and beginning). Fencing transactions allows the MUPIP JOURNAL
facility to prevent incomplete application transactions consisting of
multiple global updates from affecting the database during a database
recovery. FIS strongly recommends the use of the M transaction processing
commands such as TSTART and TCOMMIT rather than ZTSTART and ZTCOMMIT. FIS
no longer tests the deprecated ZTSTART / ZTCOMMIT functionally.
The format of the ZTCOMMIT command is:
ZTC[OMMIT][:tvexpr] [intexpr]
3 Examples
Examples
Example:
GTM>ZTCOMMIT 0
This ZTCOMMIT issued from Direct Mode would close any open ZTSTARTs.
Example:
2 ZTRigger
ZTRigger
Invokes all triggers with signatures matching the global variable name and
the command type of ZTR[IGGER]. The format of the ZTRIGGER command is:
ZTR[IGGER] gvn
Example:
GTM>write $ztrigger("S")
;trigger name: C#1# cycle: 1
+^C -commands=ZTR -xecute="write ""ZTR trigger invoked"""
1
GTM>ztrigger ^C
ZTR trigger invoked
GTM>
2 ZTStart
ZTStart
The ZTSTART command marks the beginning of a logical transaction within a
GT.M program. ZTSTART and ZTCOMMIT "fence" transactions (that is, mark the
beginning and end). Fenced transactions prevent the MUPIP JOURNAL facility
from recovering incomplete transactions. All ZTSTARTs must be matched with
ZTCOMMITs before the journal processing facility recognizes the
transaction as complete. FIS strongly recommends the use of the M
transaction processing commands such as TSTART and TCOMMIT rather than
ZTSTART and ZTCOMMIT. FIS no longer tests the deprecated ZTSTART /
ZTCOMMIT functionally.
The format of the ZTSTART command is:
ZTS[TART][:tvexpr]
For more information on Journaling and transaction fencing, refer to the
"GT.M Journaling" chapter in the GT.M Administration and Operations Guide.
2 ZWIthdraw
ZWIthdraw
The ZWITHDRAW command KILLs the data value for a variable name without
affecting the nodes descended from that node.
The format of the ZWITHDRAW command is:
ZWI[THDRAW][:tvexpr] glvn
ZWITHDRAW provides a tool to quickly restore a node to a state where it
has descendants and no value-- that is, where $DATA for that node will
have a value of 10 -- for the case where such a state has some control
meaning. GT.M also provides the ZKILL command, with functionality
identical to ZWITHDRAW.
3 Examples
Examples
Example:
Kill A
Set A="A",A(1)=1,A(1,1)=1
WRite $Data(A(1)),!
ZWIthdraw A(1)
WRite $D(A(1)),!
ZWRite A
Quit
produces the result:
11
10
A="A"
A(1,1)=1
This sets up local variables A and A(1) and A(1,1). It then deletes the
data for A(1) with ZWITHDRAW. The ZWRITE command shows ZWITHDRAW KILLed
A(1) but left A and A(1,1).
2 ZWRite
ZWRite
The ZWRITE command displays the current value of one or more local , alias
variables, ISVs, or global variables. ZWRITE formats its output so that
each item in the display forms a valid argument to a SET @ command. This
means ZWRITE encloses string values in quotes and represents non-graphic
(control) characters in $CHAR() syntax.
The format of the ZWRITE command is:
ZWR[ITE][:tvexpr] [zwrglvn[,...]]
3 ZWRITE_Format_for_Alias_Variables
ZWRITE Format for Alias Variables
ZWRITE and ZSHOW "V" dump the values of alias variables, alias container
variables, and the associated data as described below, in ZWRITE format.
In the ZWRITE format, the contents of an array are displayed with the name
associated with that array that appears first in the lexical ordering of
names. GT.M displays both the unsubscripted and subscripted nodes and
values, appending a notational space-semicolon-asterisk (";*") sequence to
the unsubscripted value, if any. The ZWRITE format output can be read into
a GT.M process with the commands Read x and Set @x (where x is any name)
executed in a loop. ";*" acts as a comment ignored by the SET command. In
the following example, since A and C are aliases associated with the same
array, the nodes of that array are output with A, which occurs lexically
before C, even though the values were assigned to C:
GTM>Set C=1,C("Malvern")="Wales",*A=C,*B(-3.14)=C
GTM>ZSHow "V" ; ZWRite would produce the same output
A=1 ;*
A("Malvern")="Wales"
*B(-3.14)=A
*C=A
GTM>ZWRite C ; Only one is name associated with the array on this ZWRite command
C=1 ;*
C("Malvern")="Wales"
GTM>
Continuing the example, if the variables selected for the ZWRITE command
do not include any of the the associated alias variables, the output shows
only the reference, not the data:
GTM>ZWRITE B ; B only has a container
*B(-3.14)=A
GTM>
When ZWRITE / ZSHOW "V" encounters an alias container for an array with no
current alias variable, it uses a name $ZWRTACn as the made-up name of an
alias variable for that array, where n is an arbitrary but unique integer.
The SET command recognizes this special name, thus enabling the output of
a ZWRITE / ZSHOW "V" to be used to recreate alias containers without
associated alias variables. Continuing the above example:
GTM>Kill *A,*C ; Delete alias variables and associations, leaving only the container
GTM>ZWRite
$ZWRTAC=""
*B(-3.14)=$ZWRTAC1
$ZWRTAC1=3 ;*
$ZWRTAC1("Malvern")="Wales"
$ZWRTAC=""
GTM>
ZWRITE produces $ZWRTACn names to serve as data cell anchors which SET @
accepts as valid set left targets. $ZWRTACn names are created and
destroyed when using ZWRITE output to drive restoration of a previously
captured variable state. Except for their appearance in ZWRITE output and
as left-hand side SET @ targets, they have no function. Other than SET, no
other commands can use $ZWRTAC* in their syntax. Although $ZWRTACn
superficially looks like an intrinsic special variable (ISV), they are not
ISVs. $ZWRTACn with no subscripts can serve as the target (left side of
the equals-sign) of a SET * command. SET $ZWRTAC (no trailing integer)
deletes all data cell associations with the $ZWRTAC prefixed aliases. GT.M
only recognizes the upper-case unabbreviated name and prefix $ZWRTAC.
When ZWRITE displays values for an alias variable, it appends a " ;*" to
the name which visually tags the alias without interfering with use of
ZWRITE output as arguments to a SET @. ZWRITE can only identify alias
variables when at least two aliases for the same data match its argument.
When ZWRITE encounters an alias container variable with no current
associated alias, it uses the ZWRTAC mechanism to expose the data; SET @
can restore data exposed with the ZWRTAC mechanism.
**Caution**
FIS strongly recommends that you should not create or manipulate your own
$ZWRTACn "variables". They are not part of the supported functionality for
implementing alias variables and containers, but are rather a part of the
underlying implementation that is visible to you, the GT.M user. FIS can
arbitrarily, for its own convenience change the use of $ZWRTAC in GT.M at
any time. They are only documented here since you may see them in the
output of ZWRITE and ZSHOW "V".
3 Examples
Examples
Example:
GTM>ZWRITE ^?1"%"2U(0:":",)
This command displays the descendants of all subscripts between 0 and ":"
of all global names starting with a "%" and having two upper case letters
-- for example, "%AB".
Example:
GTM>ZWRITE A(,:,3)
This command displays all of the third level nodes with a subscript of 3
for local variable A.
Example:
ZWRITE ?1"A".E(?1"X"3N)
This displays data for any local variables starting with "A", optionally
followed by any characters, and having any subscripts starting with "X"
followed by three numerics.
Example:
GTM>Set A=1,*B=A ; Create an array and an alias association
GTM>ZWRite ; Show that the array and association exist
A=1 ;*
*B=A
1 Functions
Functions
This chapter describes M language Intrinsic Functions implemented in GT.M.
Traditional string processing functions have parallel functions that start
with the letter "z". The parallel functions extend the byte-oriented
functionality of their counterparts to UTF-8 mode. They are helpful when
applications need to process binary data including blobs, binary byte
streams, bit-masks, and so on.
Other functions that start with the letter "z" and do not have
counterparts implement new functionality and are GT.M additions to the
ANSI standard Intrinsic Functions. The M standard specifies standard
abbreviations for Intrinsic Functions and rejects any non-standard
abbreviations.
M Intrinsic Functions start with a single dollar sign ($) and have one or
more arguments enclosed in parentheses () and separated by commas (,).
These functions provide expression results by performing actions that are
impossible or difficult to perform using M commands.
2 $ASCII()
$ASCII()
Returns the integer ASCII code for a character in the given string. For a
mumps process started in UTF-8 mode, $ASCII() returns the integer Unicode
code-point value of a character in the given string.
The format for the $ASCII function is:
$A[SCII](expr[,intexpr])
$ASCII() provides a means of examining non-graphic characters in a string.
When used with $CHAR(), $ASCII() also provides a means to perform
arithmetic operations on the codes associated with characters.
$ZASCII() is the parallel function of $ASCII(). $ZASCII() interprets the
string argument as a sequence of bytes (rather than a sequence of
characters) and can perform all byte-oriented $ASCII() operations. For
more information, refer to "$ZAscii()".
3 Examples
Examples
Example:
GTM>For i=0:1:3 Write !,$Ascii("Hi",i)
-1
72
73
-1
GTM>
This loop displays the result of $ASCII() specifying a character position
before, first and second positions, and after the string.
Example:
GTM>Write $ZCHSET
UTF-8
GTM>Write $Ascii("*")
20027
GTM>Write $$FUNC^%DH("20027")
00004E3B
In this example, 20027 is the integer equivalent of the hexadecimal value
4E3B. U+4E3B is a character in the CJK Ideograph block of the Unicode
Standard.
2 $Char()
$Char()
Returns a string of one or more characters corresponding to integer ASCII
codes specified in its argument(s). For a process started in UTF-8 mode,
$CHAR() returns a string composed of characters represented by the integer
equivalents of the Unicode code-points specified in its argument(s).
The format for the $CHAR function is:
$C[HAR](intexpr[,...])
3 Examples
Examples
Example:
GTM>write $char(77,85,77,80,83,7)
MUMPS
GTM>
This example uses $CHAR() to WRITE the word MUMPS and signal the terminal
"bell."
Example:
set nam=$extract(nam,1,$length(nam)-1)_$char($ascii(nam,$length(nam))-1)
This example uses $CHAR() and $ASCII() to set the variable nam to a value
that immediately precedes its previous value in the set of strings of the
same length as nam.
Example:
GTM>write $zchset
UTF-8
GTM>write $char(20027)
*
GTM>write $char(65)
A
In the above example, the integer value 20027 is the Unicode character "*"
in the CJK Ideograph block of Unicode. Note that the output of the $CHAR()
function for values of integer expression(s) from 0 through 127 does not
vary with choice of the character encoding scheme. This is because 7-bit
ASCII is a proper subset of UTF-8 character encoding scheme. The
representation of characters returned by the $CHAR() function for values
128 through 255 differ for each character encoding scheme.
2 $Data()
$Data()
Returns an integer code describing the value and descendent status of a
local or global variable.
The format for the $DATA function is:
$D[ATA](glvn)
The following table summarizes $DATA() return values.
+--------------------------------------------+
| $DATA() Results |
|--------------------------------------------|
| VALUE |
|--------------------------------------------|
| | DESCENDANTS (NO) | DESCENDANTS (YES) |
|-----+------------------+-------------------|
| NO | 0 | 10 |
|-----+------------------+-------------------|
| YES | 1 | 11 |
+--------------------------------------------+
$DATA() return values can also be understood as a pair of truth-values
where the left describes descendants and the right describes data 1 and
where M suppresses any leading zero (representing no descendants).
3 Examples
Examples
Example:
GTM>Kill Write $Data(a)
0
GTM>Set a(1)=1 Write $Data(a(1))
1
GTM>Write $Data(a)
10
GTM>Set a=0 Write $Data(a)
11
GTM>
This uses $DATA to display all possible $DATA() results.
Example:
lock ^ACCT(0)
if '$data(^ACCT(0)) set ^ACCT(0)=0
set (ACCT,^ACCT(0))=^ACCT(0)+1
lock
This uses $DATA() to determine whether a global node requires
initialization.
Example:
for set cus=$O(^cus(cus)) quit:cus="" if $data(^(cus))>1 do WORK
This uses $DATA() to determine whether a global node has descendants and
requires additional processing.
2 $Extract()
$Extract()
Returns a substring of a given string.
The format for the $EXTRACT function is:
$E[XTRACT](expr[,intexpr1[,intexpr2]])
$EXTRACT() provides a tool for manipulating strings based on character
positions.
For a mumps process started in UTF-mode, $EXTRACT interprets the string
arguments as UTF-8 encoded. With VIEW "BADCHAR" enabled, $EXTRACT()
produces a run-time error when it encounters a character in the reserved
range of the Unicode Standard, but it does not process the characters that
fall after the span specified by the arguments. The parallel function of
$EXTRACT() is $ZEXTRACT(). Use $ZEXTRACT() for byte-oriented operations.
$EXTRACT() can be used on the left-hand side of the equal sign (=) of a
SET command to set a substring of a string. This construct permits easy
maintenance of individual pieces within a string. It can also be used to
right justify a value padded with blank characters.
3 Examples
Examples
Example:
GTM>for i=0:1:3 write !,$extract("HI",i),"<"
<
H<
I<
<
GTM>
This loop displays the result of $EXTRACT(), specifying no ending
character position and a beginning character position "before" first and
second positions, and "after" the string.
Example:
GTM>For i=0:1:3 write !,$extract("HI",1,i),"<"
<
H<
HI<
HI<
GTM>
This loop displays the result of $EXTRACT() specifying a beginning
character position of 1 and an ending character position "before, " first
and second positions, and "after" the string.
Example:
GTM>zprint ^trim
trim(x)
new i,j
for i=1:1:$length(x) quit:" "'=$extract(x,i)
for j=$length(x):-1:1 quit:" "'=$extract(x,j)
quit $extract(x,i,j)
GTM>set str=" MUMPS "
GTM>write $length(str)
7
GTM>write $length($$^trim(str))
5
GTM>
This extrinsic function uses $EXTRACT() to remove extra leading and
trailing spaces from its argument.
2 $Find()
$Find()
Returns an integer character position that locates the occurrence of a
substring within a string.
The format for the $FIND function is:
$F[IND](expr1,expr2[,intexpr])
$FIND() provides a tool to locate substrings. The ([) operator and the
two-argument $LENGTH() are other tools that provide related functionality.
3 Examples
Examples
Example:
GTM>write $find("HIFI","I")
3
GTM>
This example uses $FIND() to WRITE the position of the first occurrence of
the character "I." The return of 3 gives the position after the "found"
substring.
Example:
GTM>write $find("HIFI","I",3)
5
GTM>
This example uses $FIND() to WRITE the position of the next occurrence of
the character "I" starting in character position three.
Example:
GTM>set t=1 for set t=$find("BANANA","AN",t) quit:'t write !,t
4
6
GTM>
This example uses a loop with $FIND() to locate all occurrences of "AN" in
"BANANA". $FIND() returns 4 and 6 giving the positions after the two
occurrences of "AN".
Example:
GTM>set str="MUMPS databases are hierarchical"
GTM>Write $find(str," ")
7
GTM>Write $find(str,"Z")
0
GTM>Write $find(str,"d",1)
8
GTM>Write $find(str,"d",10)
0
The above example searches a string for a sub string, and returns an
integer value which corresponds to the next character position after
locating the sub string.
2 $FNumber()
$FNumber()
Returns a string containing a formatted number.
The format for the $FNUMBER function is:
$FN[UMBER](numexpr,expr[,intexpr])
$FNUMBER() formats or edits numbers, usually for reporting.
The formatting codes are:
3 Examples
Examples
Example:
GTM>do ^fnum
fnum;
zprint ^fnum
set X=-100000,Y=2000
write "SUPPRESS NEGATIVE SIGN:",?35,$FNumber(X,"-"),!
write "TRAILING SIGN:",?35,$FNumber(X,"T"),!
write "NEGATIVE NUMBERS IN ():",?35,$FNumber(X,"P"),!
write "COMMAS IN NUMBER:",?35,$FNumber(X,","),!
write "NUMBER WITH FRACTION:",?35,$FNumber(X,"",2),!
write "FORCE + SIGN IF POSITIVE:",?35,$FNumber(Y,"+"),!
SUPPRESS NEGATIVE SIGN: 100000
TRAILING SIGN: 100000-
NEGATIVE NUMBERS IN (): (100000)
COMMAS IN NUMBER: -100,000
NUMBER WITH FRACTION: -100000.00
FORCE + SIGN IF POSITIVE: +2000
Example:
set x=$fnumber(x,"-")
This example uses $FNUMBER() to SET x equal to its absolute value.
2 $Get()
$Get()
Returns the value of a local or global variable if the variable has a
value. If the variable has no value, the function returns a value
specified by an optional second argument, and otherwise returns an empty
string.
The format for the $GET function is:
$G[ET](glvn[,expr])
M defines $GET(x,y) as equivalent to:
$Select($Data(x)[0:y,1:x)
and $GET(x) as equivalent to:
$GET(x,"")
$GET() provides a tool to eliminate separate initialization of variables.
This technique may provide performance benefits when used to increase the
density of a sparse global array by eliminating nodes that would otherwise
hold absent optional information. On the other hand, some uses of one
argument $GET() can mask logic problems.
GT.M has a "NOUNDEF" mode of operation, which treats all variable
references as if they were arguments to a one argument $GET(). The VIEW
command controls "NOUNDEF" mode.
3 Examples
Examples
Example:
setstatus;
if '$data(^PNT(NAME,TSTR)) set STATUS="NEW TEST"
else if ^PNT(NAME,TSTR)="" set STATUS="WAITING FOR RESULT"
else set STATUS=^PNT(NAME,TSTR)
This example can be reduced to two lines of code by using $GET(), shown in
the following example. However, by using $GET() in its one-argument form,
the distinction between an undefined variable and one with a null value is
lost:
set STATUS=$get(^PNT(NAME,TSTR))
if STATUS="" set STATUS="WAITING FOR RESULT"
This is solved by using the two-argument form of $GET():
set STATUS=$get(^PNT(NAME,TSTR),"NEW TEST")
if STATUS="" set STATUS="WAITING FOR RESULT"
2 $Increment()
$Increment()
Atomically adds (increments) a global variable by a numeric value. Note
that increment is atomic, but the evaluation of the expression is not,
unless inside a transaction (TStart/TCommit). The function also works on
local variables, but has less benefit for locals as it does not (need to)
provide ACID behavior.
The format of the $INCREMENT function is:
$INCREMENT(glvn[,numexpr])
3 Examples
Examples
Example:
GTM>set i=1
GTM>write $increment(i)
2
GTM>write $increment(i)
3
GTM>write $increment(i)
4
GTM>write $increment(i)
5
GTM>write i
5
GTM>write $increment(i,-2)
3
GTM>write I
3
GTM>
This example increments the value of i by 1 and at the end decrements it
by 2. Note that the default value for incrementing a variable is 1.
2 $Justify()
$Justify()
Returns a formatted string.
The format for the $JUSTIFY function is:
$J[USTIFY](expr,intexpr1[,intexpr2])
$JUSTIFY() fills expressions to create fixed length values. However, if
the length of the specified expression exceeds the specified field size,
$JUSTIFY() does not truncate the result (although it may still round based
on the third argument). When required, use $EXTRACT() to perform
truncation.
$JUSTIFY() optionally rounds the portion of the result after the decimal
point. In the absence of the third argument, $JUSTIFY() does not restrict
the evaluation of the expression. In the presence of the third (rounding)
argument, $JUSTIFY() evaluates the expression as a numeric value. The
rounding algorithm can be understood as follows:
3 Examples
Examples
Example:
GTM>write ":",$justify("HELLO",10),":",!,":",$justify("GOODBYE",5),":"
: HELLO:
:GOODBYE:
GTM>
This uses $JUSTIFY() to display "HELLO" in a field of 10 spaces and
"GOODBYE" in a field of 5 spaces. Because the length of "GOODBYE" exceeds
five spaces, the result overflows the specification.
Example:
GTM>write "1234567890",!,$justify(10.545,10,2)
1234567890
10.55
GTM>
This uses $JUSTIFY() to WRITE a rounded value right justified in a field
of 10 spaces. Notice that the result has been rounded up.
Example:
GTM>write "1234567890",!,$justify(10.544,10,2)
1234567890
10.54
GTM>
Again, this uses $JUSTIFY() to WRITE a rounded value right justified in a
field of 10 spaces. Notice that the result has been rounded down.
Example:
GTM>write "1234567890",!,$justify(10.5,10,2)
1234567890
10.50
GTM>
Once again, this uses $JUSTIFY() to WRITE a rounded value right justified
in a field of 10 spaces. Notice that the result has been zero-filled to 2
places.
Example:
GTM>write $justify(.34,0,2)
0.34
GTM>
This example uses $JUSTIFY to ensure that the fraction has a leading zero.
Note the use of a second argument of zero in the case that rounding is the
only function that $JUSTIFY is to perform.
2 $Length()
$Length()
Returns the length of a string measured in characters, or in "pieces"
separated by a delimiter specified by one of its arguments.
The format for the $LENGTH function is:
$L[ENGTH](expr1[,expr2])
3 Examples
Examples
Example:
GTM>Write $length("KINGSTON")
8
GTM>
This uses $LENGTH() to WRITE the length in characters of the string
"KINGSTON".
Example:
GTM>set x="Smith/John/M/124 Main Street/Ourtown/KA/USA"
GTM>write $length(x,"/")
7
GTM>
This uses $LENGTH() to WRITE the number of pieces in a string, as
delimited by /.
Example:
GTM>write $length("/2/3/","/")
4
GTM>
This also uses $LENGTH() to WRITE the number of pieces in a string, as
delimited by /. Notice that GT.M. adds one count to the count of
delimiters (in this case 3), to get the number of pieces in the string
(displays 4).
2 $NAme()
$NAme()
Returns an evaluated representation of some or all of a local or global
variable name.
The format for the $NAME function is:
$NA[ME](glvn[,intexpr])
3 Examples
Examples
Example:
GTM>set X="A""B",^Y(1,X,"B",4)=""
GTM>write $name(^(3),3)
^Y(1,"A""B","B")
GTM>
This example sets up a naked reference and then uses $NAME() to display
the first three levels of that four-level reference.
Example:
GTM>write $name(^(3),0)
^Y
GTM>
This example shows the name level for the same naked reference.
2 $Next()
$Next()
Returns the next subscripted local or global variable name in collation
sequence within the array level specified by its argument.
$NEXT() has been replaced by $ORDER(). $NEXT has been retained in the
current standard only for compatibility with earlier versions of the
standard. $NEXT() is similar to $ORDER(). However, $NEXT() has the
deficiency that when it encounters negative one (-1) as a subscript, it
returns the same result as when it finds no other data at the level. This
deficiency is particularly disruptive because it occurs in the middle of
the M collating sequence.
**Caution**
As $NEXT() has been removed from the standard in the MDC, you should use
$ORDER.
The format for the $NEXT function is:
$N[EXT](glvn)
2 $Order()
$Order()
Returns the subscript of the next or prior local or global variable name
in collation sequence within the array level specified by its first
argument. In doing so, it moves in the direction specified by the second
argument. In GT.M, when $ORDER() has an unsubscripted argument, it returns
the next or previous unsubscripted local or global variable name in
collating sequence.
The format for the $ORDER function is:
$O[RDER](glvn[,expr])
**Note**
Name-level $ORDER() always returns an empty string when used with extended
references.
3 Examples
Examples
Example:
GTM>zwrite
lcl(1)=3
lcl("x")=4
GTM>write $order(lcl(""))
1
This example returns the first node, that is 1, because the specified last
subscript of the argument is null and lcl has no null subscript.
Example:
GTM>write $order(lcl(1))
x
This example returns the first node after lcl(1) that is x because lcl has
no null subscript.
Example:
GTM>write $order(lcl(""),-1)
x
This example returns the last node that is, x, because the last subscript
of the first argument is null and second argument is -1.
GTM>set lcl("")=2
GTM>zwrite
lcl("")=2
lcl(1)=3
lcl("x")=4
GTM>write $order(lcl(""))
1
This example returns the second node at the specified level because the
null subscript at the end of the argument is ambiguous (does it specify
starting at the beginning or starting at the real node with the null
subscript?) and returning the subscript of the first node (an empty
string) would tend to create an endless loop.
Example:
GTM>write $order(lcl(""),-1)
x
GTM>write $order(lcl("x"),-1)
1
Example:
GTM>kill set (a(1),a(2000),a("CAT"),a("cat"),a("ALF"),a(12))=1
GTM>set x="" for set x=$order(a(x)) quit:x="" write !,x
1
12
2000
ALF
CAT
cat
GTM>kill a("CAT") set a(5,10)="woolworths",a("cat")="last"
GTM>set x="" for set x=$order(a(x),-1) quit:x="" write !,x
cat
ALF
2000
12
5
1
GTM>
This example uses a $ORDER() loop to display all the subscripts at the
first level of local variable a, make some changes in a, and then display
all the subscripts in reverse order. Notice that $ORDER() returns only the
existing subscripts in the sparse array and returns them in M collation
sequence, regardless of the order in which they were entered. Also,
$ORDER() does not differentiate between node A(5), which has only
descendants (no data value), and the other nodes, which have data values.
Example:
GTM>kill set (%(1),tiva(2),A(3),tiv(4),Q(5),%a(6))=""
GTM>set x="%"
GTM>write:$data(@x) !,x for set x=$order(@x) quit:x="" write !,x
%
%a
A
Q
tiv
tiva
x
GTM>set $piece(x,"z",32)=""
GTM>write:$data(@x) !,x for set x=$order(@x,-1) quit:x="" write !,x
x
tiva
tiv
Q
A
%a
%
GTM>
This example uses $ORDER() to display the current local variable names in
both forward and reverse order. Notice that the first ([^]%) and last
([^]zzzzzzzz) names require handling as special cases and require a
$DATA() function.
Example:
set acct="",cntt=""
for fet acct=$order(^acct(acct)) quit:acct="" do
. for set cntt=$order(^acct(acct,cntt)) do WORK
quit
This uses two nested $ORDER() loops to cycle through the ^acct global
array and perform some action for each second level node.
2 $Piece()
$Piece()
Returns a substring delimited by a specified string delimiter made up of
one or more characters. In M, $PIECE() returns a logical field from a
logical record.
The format for the $PIECE function is:
$P[IECE](expr1,expr2[,intexpr1[,intexpr2]])
3 Examples
Examples
Example:
GTM>for i=0:1:3 write !,$piece("1 2"," ",i),"<"
<
1<
2<
<
GTM>
This loop displays the result of $PIECE(), specifying a space as a
delimiter, a piece position "before," first and second, and "after" the
string.
Example:
GTM>for i=-1:1:3 write !,$piece("1 2"," ",i,i+1),"<"
<
1<
1 2<
2<
<
GTM>
This example is similar to the previous example except that it displays
two pieces on each iteration. Notice the delimiter (a space) in the middle
of the output for the third iteration, which displays both pieces.
Example:
for p=1:1:$length(x,"/") write ?p-1*10,$piece(x,"/",p)
This example uses $LENGTH() and $PIECE() to display all the pieces of x in
columnar format.
Example:
GTM>set $piece(x,".",25)="" write x
........................
This SETs the 25th piece of the variable x to null, with a delimiter of a
period. This produces a string of 24 periods preceding the null.
Example:
GTM>set ^x=1,$piece(^a,";",3,2)=^b
This example leaves the naked indicator to pointing to the global ^b.
2 $Qlength()
$Qlength()
Returns the number of subscripts in a variable name. The format is:
$QL[ENGTH] (namevalue)
3 Examples
Examples
Example:
GTM>write $data(^|"XXX"|ABC(1,2,3,4))
0
GTM>set X=$name(^(5,6))
GTM>write $qlength(X)
5
The number of subscripts in x is 5. Notice that the name and the
environment preceding it do not contribute to the count. Refer to $NAme()
section earlier in this chapter for an understanding of the $NAME
function.
2 $QSubscript()
$QSubscript()
Returns a component of a variable name.
The format of the $QSUBSCRIPT function is:
$QS[UBSCRIPT](namevalue, intexpr)
3 Examples
Examples
Example:
Assume that X is defined as in the "Examples of $Qlength()" earlier in
this chapter;
write X
X="^|""XXX""|ABC(1,2,3,5,6)"
GTM>write $qsubscript(X,-2)
error
GTM>WRITE $qsubscript(X,-1)
XXX
GTM>WRITE $qsubscript(X,0)
^ABC
GTM>WRITE $qsubscript(X,1)
1
GTM>WRITE $qsubscript(X,4)
5
GTM>WRITE $qsubscript(X,7)
""
2 $Query()
$Query()
Returns the next subscripted local or global variable node name,
independent of level, which follows the node specified by its argument in
M collating sequence and has a data value.
The format for the $QUERY function is:
$Q[UERY](glvn)
$QUERY() can be used as a tool for scanning an entire array for nodes that
have data values. Because $QUERY() can return a result specifying a
different level than its argument, the result provides a full variable
name. This contrasts with $ORDER(), which returns a subscript value. To
access the data value at a node, a $ORDER() return can be used as a
subscript; however, a $QUERY() return must be used with indirection.
Because arrays tend to have homogeneous values within a level but not
between levels, $QUERY() is more useful as a tool in utility programs than
in application programs. The $QUERY() can be useful in avoiding nested
$ORDER loops.
Note that the standard does not unambiguously define the state of the
naked reference indicator after a $QUERY(). While in GT.M after $QUERY(),
the naked reference indicator reflects the $QUERY() argument, NOT its
result.
3 Examples
Examples
Example:
The following routine:
set y="^X"
for set y=$query(@y) quit:y="" write !,y,"=",@y
produces the results:
^X(1,2,3)=123
^X(1,2,3,7)=1237
^X(1,2,4)=124
^X(1,2,5,9)=1259
^X(1,6)=16
^X("B",1)=AB
Example:
GTM>zwrite lcl
lcl("")=1
lcl(1)=1
lcl(1,2)=2
lcl(1,2,"")=3
lcl(1,2,"","")=4
lcl(1,2,"","",4)=5
lcl(1,2,0)=6
lcl(1,2,"abc",5)=7
lcl("x")=1
GTM>set y="lcl"
GTM>for set y=$query(@y) quit:y="" write !,y,"=",@y
This example produces the results:
lcl("")=1
lcl(1)=1
lcl(1,2)=2
lcl(1,2,"")=3
lcl(1,2,"","")=4
lcl(1,2,"","",4)=5
lcl(1,2,0)=6
lcl(1,2,"abc",5)=7
lcl("x")=1
Note that the result is the same as the ZWRITE output.
2 $Random()
$Random()
Returns a random integer from a range specified by its argument.
The format for the $RANDOM function is:
$R[ANDOM](intexpr)
$RANDOM() provides a tool for generating pseudo-random patterns useful in
testing or statistical calculations. $RANDOM() results fall between zero
(0) and one less than the argument.
Random number generators use factors from the environment to create
sequences of numbers. True random number generation requires a source of
what is known as "noise". Pseudo-random numbers appear to have no pattern,
but are developed using interactions between factors that vary in ways not
guaranteed to be entirely random. In accordance with the M standard, the
GT.M implementation of $RANDOM() produces pseudo-random numbers.
3 Examples
Examples
Example:
GTM>for i=1:1:10 write $random(1)
0000000000
GTM>
This shows that when $RANDOM() has an argument of one (1), the result is
too confined to be random.
Example:
set x=$random(100)+1*.01
This $RANDOM() example produces a number between 0 and 99. The example
then shifts with addition, and scales with multiplication to create a
value between .01 and 1.
2 $REverse()
$REverse()
Returns a string with the characters in the reverse order from that of its
argument.
The format for the $REVERSE function is:
$RE[VERSE](expr)
3 Examples
Examples
Example:
GTM>write $reverse(123)
321
GTM>write $reverse("AbCDe")
"eDCbA"
2 $Select()
$Select()
Returns a value associated with the first true truth-valued expression in
a list of paired expression arguments.
The format for the $SELECT function is:
$S[ELECT](tvexpr:expr[,...])
$SELECT() is one of a limited set of functions that permit an indefinite
number of arguments. $SELECT() provides a means of selecting from a list
of alternatives.
Generally, the last $SELECT() argument has numeric literal one (1) for a
truth-value to prevent run-time errors, and to provide a "default" value.
3 Examples
Examples
Example:
GTM>for i=3:-1:0 write !,$select(i=1:"here",i=2:"come",i=3:"Watson")
Watson
come
here
%GTM-E-SELECTFALSE, No argument to $SELECT was true
GTM>
This loop uses $SELECT() to WRITE a series of strings. Because there is no
true argument on the fourth iteration, when i=0, $SELECT() produces an
error.
Example:
set name=$select(sex="M":"Mr. ",sex="F":"Ms. ",1:"")_name
This example uses $SELECT() to add a prefix to the name based on a sex
code held in the variable sex. Notice that the default handles the case of
a missing or incorrect code.
Example:
if $select(x=+x:x,x="":0,"JANAPRJULOCT"[x:1,1:0) do THING
This uses $SELECT() to perform complex logic as the truth-valued
expression argument to an IF command.
2 $STack()
$STack()
Returns strings describing aspects of the execution environment.
The format for the $STACK function is:
$ST[ACK](intexpr[,expr])
**Note**
$STACK() returns similar information to ZSHOW "S" when ""=$ECODE, but when
$ECODE contains error information, $STACK() returns information as of the
time of a prior error, generally the first entry in $ECODE. For $STACK()
to return current information, be sure that error handing code does a SET
$ECODE="" before restoring the normal flow of control.
3 Examples
Examples
Example:
/usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^dstackex
dstackex;
zprint ^dstackex
write !,$STACK
xecute "WRITE !,$STACK"
do Label
write !,$$ELabel
write !,$STACK
quit
Label
write !,$STACK
do DLabel
quit
ELabel()
quit $STACK
DLabel
write !,$STACK
quit
0
1
1
2
1
Example for error processing:
GTM>zprint ^debugerr
debugerr;
set dsm1=$stack(-1)
write !,"$stack(-1):",dsm1
for l=dsm1:-1:0 do
. write !,l
. for i="ecode","place","mcode" write ?5,i,?15,$stack(l,i),!
GTM>
The above example can be used to display a trace of the code path that led
to an error.
Example:
GTM>zprint ^dstacktst
dstacktst(x) ; check $stack() returns with and without clearing $ecode
set $etrap="do ^debugerr"
label
if x>0 set $ecode=",U1," ; if condition
else set $ecode=",U2," ; else condition
quit
GTM>do ^dstacktst(0)
$stack(-1):2
2 ecode
place debugerr+3^debugerr
mcode for l=dsm1:-1:0 do
1 ecode ,U2,
place label+2^dstacktst
mcode else set $ecode=",U2," ; else condition
0 ecode
place +1^GTM$DMOD
mcode
%GTM-E-SETECODE, Non-empty value assigned to $ECODE (user-defined error trap)
GTM>do ^dstacktst(1)
$stack(-1):1
1 ecode ,U2,
place label+2^dstacktst
mcode else set $ecode=",U2," ; else condition
0 ecode
place +1^GTM$DMOD
mcode
%GTM-E-SETECODE, Non-empty value assigned to $ECODE (user-defined error trap)
GTM>set $ecode=""
GTM>do ^dstacktst(1)
$stack(-1):2
2 ecode
place debugerr+3^debugerr
mcode for l=dsm1:-1:0 do
1 ecode ,U1,
place label+1^dstacktst
mcode if x>0 set $ecode=",U1," ; if condition
0 ecode
place +1^GTM$DMOD
mcode
%GTM-E-SETECODE, Non-empty value assigned to $ECODE (user-defined error trap)
GTM>
This example shows how SETing $ECODE=.. makes $STACK() reports current
information. Notice how ^do dstacktst(0) and ^dostacktst(1) without
clearing $ECODE in between displays information frozen at the time of the
first error (else condition).
2 $Text()
$Text()
Returns source text for the line specified by its argument.
The format for the $TEXT function is:
$T[EXT](entryref)
$TEXT() provides a tool for examining routine source code and the name of
the current routine or trigger. $TEXT() assists, along with the ZPRINT
command, in debugging programs. $TEXT() also allows the insertion of small
tables of driver information into a routine. Because $TEXT() is not very
efficient and the table-driven technique is generally best suited to
minimal program changes, this approach is best used for prototyping and
the tables should reside in global variables for production.
If $TEXT() cannot access the source file for the current object, either
because it is not in the location from which it was compiled or because
the process does not have access to some piece of the path to the source,
or if the located source does not match the object currently in use by the
process, $TEXT() returns an empty string.
3 Examples
Examples
Example:
for i=1:1 set x=$text(+i) quit:x="" write !,x
This loop uses $TEXT() to write out the entire source for the current
routine.
Example:
GTM>write $text(+0)
GTM$DMOD
GTM>write $text(+1)
GTM>
This uses $TEXT() to WRITE the name of the current routine, then it tries
to access the source and returns an empty string. This occurs because the
default Direct Mode image is compiled by FIS and delivered without source.
The exact failure message may vary.
2 $TRanslate()
$TRanslate()
Returns a string that results from replacing or dropping characters in the
first of its arguments as specified by the patterns of its other
arguments.
The format for the $TRANSLATE function is:
$TR[ANSLATE](expr1[,expr2[,expr3]])
The $TRANSLATE() algorithm can be understood as follows:
* $TRANSLATE() evaluates each character in the first expression,
comparing it character by character to the second expression looking
for a match. If there is no match in the second expression, the
resulting expression contains the character without modification.
* When it locates a character match, $TRANSLATE() uses the position of
the match in the second expression to identify the appropriate
replacement for the original expression. If the second expression has
more characters than the third expression, $TRANSLATE() replaces the
original character with a null, thereby deleting it from the result.
By extension of this principle, if the third expression is missing,
$TRANSLATE() deletes all characters from the first expression that
occur in the second expression.
3 Examples
Examples
Example:
GTM>write $translate("ABC","CB","1")
A1
GTM>
**Note**
While this example provides an explanation for the work done by
$TRANSLATE(), it does not necessarily correspond to how GT.M implements
$TRANSLATE().
Example:
GTM>write $translate("A","AA","BC")
B
GTM>
This $TRANSLATE() example finds the first occurrence of "A" in the second
expression, which holds the first character position, and substitutes the
character in the first position of the third expression.
Example:
GTM>write $translate("BACKUP","AEIOU")
BCKP
GTM>
Because the $TRANSLATE() has only two parameters in this example, it finds
the characters in the first expression that also exist in the second
expression and deletes them from the result.
2 $View()
$View()
Returns information about an environmental factor selected by the
arguments. In GT.M, the first argument contains a keyword identifying the
environmental factor and, where appropriate, subsequent arguments select
among multiple possible occurrences of that factor.
The format for the $VIEW() function is:
$V[IEW](expr1[,expr2])
3 Argument_Keywords_of_$VIEW()
Argument Keywords of $VIEW()
$VIEW() provides a means to access GT.M environmental information. When
GT.M permits modification of the factors accessible with $VIEW(), the VIEW
command generally provides the means for effecting the change.
+----------------------------------------------------------------------------------------------------------------------------------------------------+
| $VIEW() Argument Keywords |
|----------------------------------------------------------------------------------------------------------------------------------------------------|
| ARG 1 | ARG 2 | RETURN VALUE |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"BADCHAR" |none |In UTF-8 mode processes, enables or disable the generation of an error when character-oriented functions encounter |
| | |malformed byte sequences (illegal characters). The default is 1. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"BREAKMSG" |none |Value of the break message mask; GT.M defaults this to 31. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"FREEBLOCKS" |region |Number of free database blocks in a given region. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| | |Process-id of a process that has frozen the database associated with the region specified (using DSE or MUPIP). |
|"FREEZE" |region | |
| | |If the region is currently not frozen, returns zero. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| | |Returns a string describing the current compiler setting. The default is "GT.M Boolean short-circuit". |
|"FULL_BOOLEAN" |none |$VIEW("FULL_BOOLEAN") reports "Standard Boolean evaluation side effects" when it is not explicitly set, but that |
| | |mode of operation is required by the setting of gtm_side_effects, and "Standard Boolean side-effect warning" when |
| | |warnings have been specified. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| | |Truth Value indicating whether Database block certification is currently enabled or disabled. |
|"GDSCERT" |none | |
| | |To enable or disable Database block certification, use the VIEW "GDSCERT" command. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"GVACCESS_METHOD"|region |Access method of the region. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"GVFILE" |region |Name of the database associated with the region. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"GVFIRST" |none |Name of the first database region in the current global directory; functionally equivalent to $VIEW("GVNEXT",""). |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"GVNEXT" |region |Name of the next database region after the given one in alphabetical order (or M collation sequence); "" for region|
| | |starts with the first region. A return value of "" means that the global directory defines no additional regions. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| | |Encoded information about database behavior since segment creation. It also includes SET operations even if they |
| | |are inside a TP transaction. |
| | | |
|"GVSTAT" |region |If you require completely accurate GVSTATS, you need to ensure the last process to close a database always has |
| | |write access to the database files. If read-only processes are the active processes in a database, they cannot |
| | |update the database and may delete the shared memory where they have stored the counts of their actions (for |
| | |example, the number of blocks read). |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| | |Number of indirection cache hits since GT.M process startup. |
|"ICHITS" |none | |
| | |Indirection cache is a pool of compiled expressions that GT.M maintains for indirection and XECUTE. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"ICMISS" |none |Number of indirection cache misses since GT.M process startup. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| | |can return the following values: |
| | | |
|"JNLACTIVE" |region | * -1 (internal error) |
| | | * 0 journaling is disabled |
| | | * 1 journaling is enabled but closed (OFF) |
| | | * 2 journaling is enabled and open (ON) |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"JNLFILE" |region |Journal file name associated with the region. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"JNLTRANSACTION" |none |Index showing how many ZTSTART transaction fences have been opened (and not closed). |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"LABELS" |none |Truth value showing whether label case sensitivity is ON (1 for "LOWER") or OFF (0 for "UPPER"); GT.M defaults to |
| | |1. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"LINK" |none |Returns the current relink recursive setting of ZLINK. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| |local variable|returns the number of references by alias containers to the array associated with an unsubscripted local variable |
|"LV_CREF" |name (lvn) |name specified as a second expr (for example a quoted string); it returns a zero for a variable without any |
| | |associated alias container. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"LV_GCOL" |none |returns the number of data-spaces recovered during a local variable data-space garbage collection it triggers; such|
| | |collections normally happen automatically at appropriate times. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"LV_REF" |local variable|returns the total number of references to the data-space associated with an unsubscripted local variable name |
| |name (lvn) |specified as a second expr (for example a quoted string). |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"LVNULLSUBS" |none |Truth value showing whether null subscripts are permitted in local arrays (1 for "LVNULLSUBS") or not (0 for |
| | |"NOLVNULLSUBS"); GT.M defaults to 1. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| | |The current isolation-status of the specified global variable which must have a leading "^" in its specification. |
| | | |
| | |This function returns 1 if GT.M has been instructed to not enforce the ACID property of Isolation (that is, |
|"NOISOLATION" |global |"NOISOLATION" has been specified) and 0 otherwise. |
| | | |
| | |By default, GT.M ensures Isolation, that is, a $VIEW command will return 0. The isolation-status of a global |
| | |variable can be turned on and off by the VIEW "NOISOLATION" command. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| | |Name of the region(s) holding the specified gvn. |
| | | |
| | |If gvn spans more than one region, this function returns region name in an order where the first region is the |
| | |region to which the unsubscripted global variable name maps; and other regions are in the order in which they would|
|"REGION" |gvn |be encountered by traversing the subscripts of gvn in order (with duplicates removed). |
| | | |
| | |gvn is a subscripted or unsubscripted global variable name in the same form as that generated by $NAME(). You can |
| | |use $NAME() inside $VIEW() to ensure that subscripts are in a correct form, for example, |
| | |$VIEW("REGION",$NAME(^abcd(1,2E4))) instead of $VIEW("REGION","^abcd(1,20000)"). |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"PATCODE" |none |Name of the active patcode table; GT.M defaults this to "M". |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"RTNCHECKSUM" |routine name |Returns the source check-sum for the most recently ZLINK'd version of the specified routine name. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"RTNNEXT" |routine name |Name of the next routine in the image after the given one; "" (empty string) for routinename starts with the first |
| | |routine in ASCII collating sequence and a return value of the empty string indicates the end of the list. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| | |Number of bytes in the currently allocated as process working storage. GT.M manages this space as what is commonly |
|"SPSIZE" |none |called a heap, and uses the term stringpool to refer to it. The GT.M garbage collector reclaims unused space from |
| | |the stringpool from time to time, and GT.M automatically expands the stringpool as needed by the application |
| | |program. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"STKSIZ" |none |Returns the GT.M stack size in bytes. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"TOTALBLOCKS" |region |Total number of database blocks in a given region. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| |NULL |Transaction ID specified in the particular level (when the transaction level is specified). The first level TSTART |
| | |is returned if the level is not specified as second argument. |
| |or | |
|"TRANSACTIONID" | | **Note** |
| |transaction | |
| |level |A NULL string is returned if the specified level (explicitly or implicitly) is greater than the current value of |
| | |$TLEVEL. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"UNDEF" |none |Truth value showing whether undefined variables should be treated as having a null value (1 for "UNDEF"; 0 for |
| | |"NOUNDEF"); GT.M defaults to 0. |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| | |Displays the database representation of gvn where gvn is a global name or a global name with subscript(s). The |
| | |option collnum specifies the alternate collation sequence number. If collnum is not specified, GT.M assumes the |
| | |default ASCII collation(collnum=0). For example: |
|"YGVN2GDS" |gvn[,collnum])| |
| | |GTM>set x=$VIEW("YGVN2GDS","^A(1,""abcd"")") zwrite x for i=1:1:$zlength(x) write $zascii($zextract(x,i))," " |
| | |x="A"_$C(0)_" "_$C(17,0,255)_"abcd"_$C(0,0) |
| | |65 0 191 17 0 255 97 98 99 100 0 0 |
| | |GTM> |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
| | |Displays the global name or a global name with subscript(s) of a database representation gds. The option collnum |
| | |specifies the collnum specifies the alternate collation sequence number. If collnum is not specified, GT.M assumes |
| | |the default ASCII collation(collnum=0). This function is the inverse of the $VIEW("YGVN2GDS",<gvn>[,collnum]) |
| | |function. For example: |
|"YGDS2GVN" |gds[,collnum])| |
| | |GTM>set y=$VIEW("YGDS2GVN",x) zwrite y |
| | |y="^A(1,""abcd"")" |
| | | |
| | |GTM> |
|-----------------+--------------+-------------------------------------------------------------------------------------------------------------------|
|"ZDATE_FORM" |none |Integer value showing whether four digit year code is active for $ZDATE(); GT.M defaults to 0 (for "YY" format). |
| | |Use the environment variable gtm_zdate_form to set the initial value of this factor. |
+----------------------------------------------------------------------------------------------------------------------------------------------------+
**Important**
FIS uses the LC_CREF, LV_GCOL, LV_REF keywords in testing and is
documenting them to ensure completeness in product documentation. They may
(or may not) be useful during application development for debugging or
performance testing implementation alternatives.
3 Examples
Examples
Example:
GTM>Set a=1,*b(1)=a
GTM>write $view("LV_CREF","a")," ",$view("LV_CREF","b")
1 0
GTM>write $view("LV_REF","a")," ",$view("LV_REF","b")
2 1
GTM>
This example creates an alias variable and an alias container variable and
checks the number of both container references and total references to the
cells associated with both a and b.
Example:
GTM>Set *a(1)=b,*b(1)=a
GTM>kill *a,*b
GTM>write $view("LV_GCOL")
2
GTM>
This example creates two cross associated alias containers, destroys their
ancestor nodes with KILL * and uses $VIEW("LV_GCOL") to force a clean-up
of the abandoned data-spaces. In the absence of the $VIEW("LV_GCOL"), GT.M
would do this automatically at some subsequent convenient time.
Example:
GTM>write $view("GVSTAT","DEFAULT")
SET:203,KIL:12,GET:203,DTA:2,ORD:23,ZPR:21,QRY:0,LKS:0,LKF:0,CTN:44,DRD:103,DWT:
59,NTW:24,NTR:55,NBW:27,NBR:138,NR0:0,NR1:0,NR2:0,NR3:0,TTW:17,TTR:5,TRB:0,TBW:3
2,TBR:80,TR0:0,TR1:0,TR2:0,TR3:0,TR4:0,TC0:0,TC1:0,TC2:0,TC3:0,TC4:0,ZTR:7
GTM>
These are statistics associated with the DEFAULT region. Refer to
"ZSHOW Information Codes" for information on the parameters.
Example:
Given the following global directory configuration:
GDE>add -name a(1:10) -region=a1
GDE>add -name a(10,1) -region=a2
GDE>add -name a(10,2) -region=a3
GDE>add -name a(120:300) -region=a4
GDE>add -name a(60:325) -region=a5
GDE> show -name
*** NAMES ***
Global Region
------------------------------------------------------------------------------
* DEFAULT
a(1:10) A1
a(10,1) A2
a(10,2) A3
a(60:120) A5
a(120:300) A4
a(300:325) A5
Here are some $VIEW("REGION",gvn) outputs:
GTM>write $view("REGION","^a(1)")
A1
GTM>write $view("REGION","^a(10)")
DEFAULT,A2,A3
GTM>w $view("REGION","^a(60)")
A5
GTM>w $view("REGION","^a")
DEFAULT,A1,A2,A3,A5,A4
2 $ZAHandle()
$ZAHandle()
$ZAHANDLE() returns a unique identifier (handle) for the array associated
with a name or an alias container; for an subscripted lvn, it returns an
empty string. To facilitate debugging, the handle is a printable string
representation of a hexadecimal number. The only meaningful operation on
the value returned by a call to $ZAHANDLE() is to compare it for equality
with the value returned by another call. Changing nodes within the array
doesn't change its handle. $ZAHANDLE() returns different results for
copies of an array.
Example:
GTM>set A=1,*B(1)=A
GTM>write "$zahandle(A)=""",$zahandle(A),""" $zahandle(B(1))=""",$zahandle(B(1)),""""
$zahandle(A)="17B8810" $zahandle(B(1))="17B8810"
GTM>set A("Subscript")="Value" ; Change array - but $ZAHandle() doesn't change
GTM>write "$zahandle(A)=""",$zahandle(A),""" $zahandle(B(1))=""",$zahandle(B(1)),""""
$zahandle(A)="17B8810" $zahandle(B(1))="17B8810"
GTM>merge D=A ; A copy of the data has a different $zahandle()
GTM>Write "$ZAHandle(A)=""",$ZAHandle(A),""" $ZAHandle(D)=""",$ZAHandle(D),""""
$zahandle(A)="17B8810" $zahandle(D)="17B8C10"
GTM>
Since GT.M does not provide a way for a function to return an array or
alias variable as its result, the uniqueness of $ZAHandle() can be
exploited to effect this capability, by placing the result in a local
variable with an agreed prefix (e.g., "%") and its $ZAHANDLE() as a
suffix. The handle can be returned as the value.
$ /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run retval
retval ; Return an array / object from a function
;;Data for the object array
;;Albert Einstein,14-March-1879
;;Arthur Eddington,28-December-1882
;;
zprint ; Print this program
new tmp1,tmp2,tmp3
for i=3:1 set tmp1=$text(+i),tmp2=$piece(tmp1,";;",2) quit:'$length(tmp2) do
.set tmp3="%"_$$NewPerson($piece(tmp2,",",1),$piece(tmp2,",",2))
.set @("*Relativists("_(i-2)_")="_tmp3)
.kill @("*"_tmp3)
kill tmp1,tmp2,tmp3
write "------------",!
write "Array of objects of relativists:",!
zwrite
quit
;
NewPerson(name,birthdate) ; Create new person object
new lname,fname,dob,tmp1,tmp2 ; New variables used by this function
set lname=$Piece(name," ",2),fname=$Piece(name," ",1)
set dob=$$FUNC^%DATE(birthdate)
set tmp1("fname")=fname,tmp1("lname")=lname,tmp1("dob")=dob
set tmp2=$ZAHandle(tmp1)
set @("*%"_tmp2_"=tmp1")
quit tmp2
------------
Array of objects of relativists:
$ZWRTAC=""
*Relativists(1)=$ZWRTAC1
$ZWRTAC1("dob")=13952
$ZWRTAC1("fname")="Albert"
$ZWRTAC1("lname")="Einstein"
*Relativists(2)=$ZWRTAC2
$ZWRTAC2("dob")=15337
$ZWRTAC2("fname")="Arthur"
$ZWRTAC2("lname")="Eddington"
i=5
$ZWRTAC=""
$
2 $ZBIT_Functions
$ZBIT Functions
A series of functions beginning with $ZBIT lets you manipulate a bit
stream. Internally, GT.M stores a bit stream in the form of a bit string.
A bit string embeds a bit stream in such a way that the first byte
specifies the number of trailing bits in the last byte that are not part
of the bit-stream. In this way, GT.M is able to store bit-streams of
lengths other than multiples of 8 bits in byte format. So for example, a
first byte of value of zero (0) indicates that all of the bits in the last
byte belong to the bit-stream, while a one (1) indicates the last bit is
excluded and a seven (7) indicates that only the first bit in the last
byte belongs to the bit-stream.
If you have to convert a character string into a bit string then add a
leading byte to that character string so that all $ZBIT functions can
recognize it. The most common and straightforward way of doing this is to
concatenate a $CHAR(n) on the front of the character string, where the
value of n is zero through seven (0-7) - most commonly zero (0). If you
pass a bit string as an argument to a routine that is expecting a
character string, then that caller routine must strip off the first (and
possibly the last) byte so that it can recognize the character string.
This section contains the description of all $ZBIT function and an example
of using $ZBIT functions to turn a character into a bit stream and return
a coded value. However, the most appropriate use of these functions may
include the formation of checksums, handling of bit-data (say pixels from
a scan), or interfacing with a routine that requires bit-oriented
arguments.
3 $ZBITAND()
$ZBITAND()
Performs a logical AND function on two bit strings and returns a bit
string equal in length to the shorter of the two arguments (containing set
bits in those positions where both of the input strings have set bits).
Positions corresponding to positions where either of the input strings
have a cleared bit, also have cleared bits in the resulting string.
The format for the $ZBITAND() function is:
$ZBITAND(expr1,expr2)
4 Example_of_$ZBITAND()
Example of $ZBITAND()
GTM>
; The binary representation of A is 01000001
GTM>Set BITSTRINGB=$zbitset($zbitset($zbitstr(8,0),2,1),7,1)
; The binary representation of B is 01000010
GTM>set BITSTRINGAB=$zbitand(BITSTRINGA,BITSTRINGB)
GTM>for i=1:1:8 write $zbitget(BITSTRINGAB,I)
01000000
This examples uses $ZBITAND to perform a bitwise AND operation on A and B.
A= 01000001
B= 01000010
A bitwise AND B=0100000
3 $ZBITCOUNT()
$ZBITCOUNT()
Returns the number of ON bits in a bit string.
The format for the $ZBITCOUNT function is:
$ZBITCOUNT(expr)
4 Example_of_$ZBITCOUNT()
Example of $ZBITCOUNT()
Example:
GTM>set BITSTRINGA=$ZBITSET($ZBITSET($ZBITSTR(8,0),2,1),8,1)
; The binary representation of A is 01000001
GTM>set BITSTRINGB=$zbitset($zbitset($zbitstr(8,0),2,1),7,1)
; The binary representation of B is 01000010
GTM>Set BITSTRINGC=$zbitor(BITSTRINGA,BITSTRINGB)
; A OR B=01000011
GTM>write $zbitcount(BITSTRINGA)
2
GTM>write $zbitcount(BITSTRINGB)
2
GTM>write $zbitcount(BITSTRINGC)
3
GTM>
This example displays the number of ON bits in BITSTRINGA, BITSTRINGB, and
BITSTRINGC.
3 $ZBITFIND()
$ZBITFIND()
Performs the analog of $FIND() on a bit string. It returns an integer that
identifies the position after the first position equal to a truth-valued
expression that occurs at, or after, the specified starting position.
The format for the $ZBITFIND function is:
$ZBITFIND(expr,tvexpr[,intexpr])
If the optional integer argument exceeds the length of the string, or if
the function finds no further bits, $ZBITFIND() returns a zero value.
4 Examples
Examples
Example:
GTM>Set BITSTRINGA=$ZBITSET($ZBITSET($ZBITSTR(8,0),2,1),8,1)
; The binary representation of A is 01000001
GTM>write $zbitfind(BITSTRINGA,1,3)
9
GTM>
This example searches for bit value 1 starting from the 3rd bit of
BITSTRINGA.
3 $ZBITGET()
$ZBITGET()
Returns the value of a specified position in the bit string.
The format for the $ZBITGET function is:
$ZBITGET(expr,intexpr)
4 Examples
Examples
Example:
GTM>set BITSTRINGA=$zbitset($zbitset($zbitstr(8,0),2,1),8,1)
; The binary representation of A is 01000001
GTM>for i=1:1:8 write $zbitget(BITSTRINGA,I)
01000001
GTM>
This examples uses $ZBITGET() to display the binary representation of A.
3 $ZBITLEN()
$ZBITLEN()
Returns the length of a bit string, in bits.
The format for the $ZBITLEN function is:
$ZBITLEN(expr)
4 Examples
Examples
GTM>set BITSTR=$zbitstr(6,1)
GTM>write $zbitlen(BITSTR)
6
GTM>
This example displays the length of a bit string of 6 bits.
3 $ZBITNOT()
$ZBITNOT()
Returns a copy of the bit string with each input bit position inverted.
The format for the $ZBITNOT function is:
$ZBITNOT(expr)
4 Examples
Examples
GTM>set BITSTRINGA=$zbitset($zbitset($zbitstr(8,0),2,1),8,1)
; The binary representation of A is 01000001
GTM>for i=1:1:8 write $zbitget($zbitnot(BITSTRINGA),I)
10111110
GTM>
This example displays inverted bits for all the bits in BITSTRINGA.
3 $ZBITOR()
$ZBITOR()
Performs a bitwise logical OR on two bit strings, and returns a bit string
equal in length to the longer of the two arguments (containing set bits in
those positions where either or both of the input strings have set bits).
Positions that correspond to positions where neither input string has a
set bit have cleared bits in the resulting string.
The format for the $ZBITOR function is:
$ZBITOR(expr1,expr2)
4 Examples
Examples
GTM>set BITSTRINGA=$zbitset($zbitset($zbitstr(8,0),2,1),8,1)
; The binary representation of A is 01000001
GTM>set BITSTRINGB=$zbitset($zbitset($zbitstr(8,0),2,1),7,1)
; The binary representation of B is 01000010
GTM>set BITSTRINGC=$zbitor(BITSTRINGA,BITSTRINGB)
; A OR B=01000011
GTM>write BITSTRINGC
C
GTM>
This example displays the result of BITSTRINGA bitwise ORed with
BITSTRINGB.
3 $ZBITSET()
$ZBITSET()
Returns an edited copy of the input bit string with a specified bit set to
the value of the truth-valued expression.
The format for the $ZBITSET function is:
$ZBITSET(expr,intexpr,tvexpr)
4 Examples
Examples
GTM>set X="A",Y=$extract($zbitset($char(0)_X,3,1),2) zwrite
X="A"
Y="a"
This example changes the case of the ASCII letter A to the corresponding
lowercase version.
3 $ZBITSTR()
$ZBITSTR()
Returns a bit string of a specified length with all bit positions
initially set to either zero or one.
The format for the $ZBITSTR function is:
$ZBITSTR(intexpr[,tvexpr])
4 Examples
Examples
GTM>set BITSTR=$zbitstr(6,1)
This example sets the value of expression BITSTR to 6 bit with all bits
set to 1.
3 $ZBITXOR()
$ZBITXOR()
Performs a bitwise exclusive OR on two bit strings, and returns a bit
string equal in length to the shorter of the two arguments (containing set
bits in those position where either but not both of the input strings have
set bits). Positions that correspond to positions where neither or both
input string has a set bit have cleared bits in the resulting string.
The format for the $ZBITXOR function is:
$ZBITXOR(expr1,expr2)
4 Examples
Examples
GTM>set BITSTRINGA=$zbitset($zbitset($zbitstr(8,0),2,1),8,1) ; The binary representation of A is 01000001
GTM>set BITSTRINGB=$zbitset($zbitset($zbitstr(8,0),2,1),7,1); The binary representation of B is 01000010
GTM>set BITSTRINGC=$zbitor(BITSTRINGA,BITSTRINGB) ; A XOR B=00000011
GTM>for I=1:1:8 write $zbitget(BITSTRINGC,I)
00000011
GTM>
This example displays the result of the bitwise XOR of A and B.
3 Examples
Examples
Example:
ZCRC(X)
new R,I,J,B,X1,K
set R=$zbitstr(8,0)
for I=1:1:$length(X) Set R=$zbitxor(R,$$bitin($A(X,I)))
quit $$bitout(R)
bitin(X) ;CONVERT A BYTE TO A BIT STRING
set X1=$zbitstr(8,0)
for J=1:1:8 set B=X#2,X=X\2 if B set X1=$zbitset(X1,J,1)
quit X1
bitout(X) ; CONVERT A BITSTRING TO A NUMBER
set X1=0
for K=1:1:8 I $zbitget(X,K) set X1=X1+(2**(K-1))
quit X1
This uses several $ZBIT functions to turn a character into a bit stream
and return a coded value.
While this example illustrates the use of several of the $ZBIT functions,
the following example produces identical results if you need to code the
function illustrated above for production.
ZCRC(X)
new R,I,J,B,X1,K
set R=$zbitstr(8,0)
for I=1:1:$length(X) Set R=$zbitxor(R,$char(0)_$extract(X,I))
quit $ascii(R,2)
This example illustrates the use of $Char() to specify the number of
invalid bits that exist at the end of the character string. In this case
there are zero invalid bits.
2 $ZAscii()
$ZAscii()
Returns the numeric byte value (0 through 255) of a given sequence of
octets (8-bit bytes).
The format for the $ASCII function is:
$ZA[SCII](expr[,intexpr])
3 Examples
Examples
Example:
GTM>for i=0:1:4 write !,$zascii("*",i)
-1
228
184
187
-1
GTM>
This UTF-8 mode example displays the result of $ZASCII() specifying a byte
position before, first, second and third positions, and after the sequence
of octets (8-bit bytes) represented by *. In the above example, 228, 184,
and 187 represents the numeric byte value of the three-byte in the
sequence of octets (8-bit bytes) represented by *.
2 $ZCHar()
$ZCHar()
Returns a string composed of bytes represented by the integer octet values
specified in its argument(s).
The format for the $ZCHAR() function is:
$ZCH[AR](intexpr[,...])
3 Example_of_$ZCHAR()
Example of $ZCHAR()
Example:
GTM>write $zchar(228,184,187,7)
*
GTM>
This example WRITEs the byte sequence represented by * and signals the
terminal bell.
2 $ZCOnvert()
$ZCOnvert()
Returns its first argument as a string converted to a different encoding.
The two argument form changes the encoding for case within a character
set. The three argument form changes the encoding scheme.
The format for the $ZCONVERT() function is:
$ZCO[NVERT](expr1, expr2,[expr3])
**Note**
When UTF-8 mode is enabled, GT.M uses the ICU Library to perform case
conversion. As mentioned in the Theory of Operation section, the case
conversion of the strings occurs according to Unicode code-point values.
This may not be the linguistically or culturally correct case conversion,
for example, of the names in the telephone directories. Therefore,
application developers must ensure that the actual case conversion is
linguistically and culturally correct for their specific needs. The
two-argument form of the $ZCONVERT() function in M mode does not use the
ICU Library to perform operation related to the case conversion of the
strings.
3 Examples
Examples
Example:
GTM>write $zconvert("Happy New Year","U")
HAPPY NEW YEAR
Example:
GTM>write $ZCHSET
M
GTM>Write $zconvert("HAPPY NEW YEAR","T")
%GTM-E-BADCASECODE, T is not a valid case conversion code
Example:
GTM>Set T8="************"
GTM>Write $Length(T8)
12
GTM>Set T16=$zconvert(T8,"UTF-8","UTF-16LE")
GTM>Write $length(T16)
%GTM-E-BADCHAR, $ZCHAR(129,137,232,150) is not a valid character in the UTF-8 encoding form
GTM>Set T16=$ZCOnvert(T16,"UTF-16LE","UTF-8")
GTM>Write $length(T16)
9
In the above example, $LENGTH() function triggers an error because it
takes only UTF-8 encoding strings as the argument.
2 $ZDATA()
$ZDATA()
Extends $DATA() to reflects the current alias state of the lvn or name
argument to identify alias and alias container variables. It treats
variables joined through pass-by-reference as well as TP RESTART variables
within a transaction as alias variables. However, it does not distinguish
nodes having alias containers among their descendants.
In addition to the four standard M results from $DATA(), $ZDATA() returns:
Existing $DATA() tests for data and descendants report on alias and alias
container variables, as well as other variables in the standard fashion.
When an application uses alias and alias container variables $ZDATA()
supplies additional information when needed.
3 Examples
Examples
Example:
GTM>set a=1,*b(1)=a,*c=d
GTM>write $data(a)," ",$zdata(a)
1 101
GTM>write $data(b)," ",$zdata(b)
10 10
GTM>write $data(c)," ",$zdata(c)
0 100
GTM>write $data(d)," ",$zdata(d)
0 100
GTM>write $data(b(1))," ",$zdata(b(1))
1 101
GTM>set b(1,2)=2
GTM>write $data(b(1))," ",$zdata(b(1))
11 111
GTM>write $data(b(1,2))," ",$zdata(b(1,2))
1 1
GTM>
2 $ZDate()
$ZDate()
Returns a date and/or time formatted as text based on an argument
formatted in the manner of $HOROLOG.
The format for the $ZDATE function is:
$ZD[ATE](expr1[,expr2[,expr3[,expr4]]]])
$ZDATE() provides an easy and flexible tool for putting M internal
date/time ($HOROLOG) formats into more user-friendly formats.
**Warning**
$ZDATE() generates an error for input date values greater than
31-Dec-999999 (364570088) or less than 01-JAN-1840 (-365) and for time
values greater than a second before midnight (86399) or less than 0
(zero).
The Intrinsic Special Variable $ZDATEFORM determines the output format for
years. The default value is zero (0), in which case $ZDATE() with one
argument (no format specification) uses a "YY" (two digit) format for all
years. If $ZDATEFORM is one (1), a "YYYY" (four digit) format is used for
years later than 1999. For all other values of $ZDATEFORM, "YYYY" (four
digit) format is used for all years. $ZDATEFORM does not affect $ZDATE()
when the format argument is specified.
The following table summarizes the usage of $ZDATE() when only first
argument is specified.
+------------------------------------------------------------------------+
| Value of $ZDATEFORM | $ZDATE() Output Format |
|---------------------+--------------------------------------------------|
| 0 | 2 digits |
|---------------------+--------------------------------------------------|
| | 4 digits for years 2000 and after |
| 1 | |
| | 2 digits otherwise (for years ranging between |
| | 1840, 1999) |
|---------------------+--------------------------------------------------|
| other | 4 digits |
+------------------------------------------------------------------------+
3 $ZDATE_Format_Specification_Elements
$ZDATE Format Specification Elements
This section lists the $ZDATE format specification elements. $ZDATE()
format specifications must appear in upper case. When any alphabetic
characters in format specifications are in lower case, $ZDATE() generates
a run-time error.
YY: Outputs the rightmost two digits of the year.
YEAR: Outputs the year as a four-digit number.
YYYYYY: Outputs the year as a six-digit number.
MM: Outputs the month as a two-digit zero-filled number between 01 and 12.
MON: Outputs the month as a three-letter abbreviation. (You can modify the
output further using expr3).
DD: Outputs the day of the month as a two-digit zero-filled number between
01 and 31.
DAY: Outputs the day of the week as a three-letter abbreviation. (You can
modify the output further using expr4).
24: Outputs the hour of the day as a zero-filled number between 00 and 23.
12: Outputs the hour of the day as a zero-filled number between 01 and 12.
60: Outputs the minute of the hour as a zero-filled number between 00 and
59.
SS: Outputs the second of the minute as a zero-filled number between 00
and 59.
AM: Outputs the letters AM and PM depending on the time.
+: Inserts a plus sign (+) in the output string
-: Inserts a minus sign (-) in the output string.
.: Inserts a period (.) in the output string.
,: Inserts a comma (,)in the output string.
/: Inserts a slash (/) in the output string.
:: Inserts a colon (:) in the output string.
;: Inserts a semi-colon (;) in the output string.
*: Inserts an asterisk (*) in the output string.
**Note**
A blank space inserts a blank space in the output string.
3 Examples
Examples
Example:
GTM>write $horolog,!,$zdate($H)
62109,60946
01/18/11
GTM>
This displays $HOROLOG and then uses $ZDATE() to display today's date. The
output shown would appear if today were the eighteenth day of January,
2011.
Example:
GTM>write $zdate($H,"DD-MON-YEAR")
18-JAN-2011
GTM>
This uses the second argument to specify a text format different from the
default.
Example:
GTM>set m="Januar,Februar,Marz,April,Mai,Juni,Juli,August,"
GTM>set m=m_"September,October,November,Dezember"
GTM>write $zdate($horolog,"DD-MON-YEAR",m)
18-Januar-2011
GTM>
This is similar to the prior example, however it uses the third argument
to specify the months in German.
Example:
GTM>set d="Dimanche,Lundi,Mardi,Mercredi,Jeudi,Vendredi,Samedi"
GTM>write $zdate($H,"DAY, DD/MM/YY","",d)
Mardi, 18/01/2011
GTM>
This example displays the eighteenth of January, however it uses the
fourth argument to specify the days of the week in French.
Example:
GTM>write !,$zdate($H,"12:60:SS AM")
10:35:51 PM
GTM>
This example shows hours, minutes, and seconds in a 12 hour clock with an
AM/PM indicator.
Example:
GTM>write !,$zdate(",36524","24-60")
10-08
GTM>
This example shows hours and minutes on a 24 hour clock. Notice that the
first argument must provide the time in the second comma delimiter piece
to match $HOROLOG format.
Example:
GTM>write $zdateform
0
GTM>write $zdate($H)
01/18/11
GTM>set $zdateform=1
GTM>write $zdate($horolog)
01/18/2011
GTM>write $zdate($horolog,"MM/DD/YY")
01/18/11
This example converts the output format for years from the default ("YY")
format to the four digit format ("YYYY") using the Intrinsic Special
Variable $ZDATEFORM.
Example:
GTM>write $zdate(123456789,"DAY MON DD, YYYYYY")
FRI MAR 17, 339854
GTM>
This example displays year as a six-digit number.
2 $ZExtract()
$ZExtract()
Returns a byte sequence from a given sequence of octets (8-bit bytes).
The format for the $ZEXTRACT function is:
$ZE[XTRACT](expr[,intexpr1[,intexpr2]])
3 Examples
Examples
Example:
GTM>Set A="************"
GTM>For i=0:1:$zlength(A)
GTM>write !,$zascii($zextract(A,i)),"|"
GTM>
This example displays the numeric byte sequence of the sequence of octets
("************").
2 $ZFind()
$ZFind()
Returns an integer byte position that locates the occurrence of a byte
sequence within a sequence of octets(8-bit bytes).
The format of the $ZFIND function is:
$ZF[IND](expr1,expr2[,intexpr])
3 Examples_of_$ZFind()
Examples of $ZFind()
Example:
GTM>write $zfind("***",$zchar(187))
4
GTM>
This example uses $ZFIND() to WRITE the position of the first occurrence
of the numeric byte code 150. The return of 3 gives the position after the
"found" byte.
Example:
GTM>write $zfind("***",$zchar(229),5)
8
GTM>
This example uses $ZFIND() to WRITE the position of the next occurrence of
the byte code 229 starting in byte position five.
Example:
GTM>set t=1 for set t=$zfind("***",$zchar(230,150,176),t) quit:'t write !,t
4
GTM>
This example uses a loop with $ZFIND() to locate all the occurrences of
the byte sequence $ZCHAR(230,150,176) in the sequence of octets ("***").
The $ZFIND() returns 4 giving the position after the occurrence of byte
sequence $ZCHAR(230,150,176).
2 $ZGetjpi()
$ZGetjpi()
Returns job or process information of the specified process. The format
for the $ZGETJPI function is:
$ZGETJPI(expr1,expr2)
Example:
GTM>write $zgetjpi(1975,"isprocalive")
1
GTM>
This uses $ZGETJPI() to determine whether process 1975 is alive.
Example:
GTM>set t=$zgetjpi("","cputim")
GTM>do ^bench write $zgetjpi("","cputim")-t
1738
GTM>
This uses $ZGETJPI() to measure the actual CPU time, measured in
hundredths of a second, consumed by performing the BENCH routine.
2 $ZJOBEXAM()
$ZJOBEXAM()
Returns the full specification of the file into which the function places
a ZSHOW "*". The return value serves as a way to save, to notify others of
the exact location of the output, or to open the file for further
processing. GT.M reports each $ZJOBEXAM() to the operator log facility
with its file specification.
The optional expression argument is a template output device
specification. It can be a device, a file directory, or a file name. The
template is an expression that is pre-processed to create a file
specification as the target for the ZSHOW. The preprocessing is equivalent
to $ZPARSE(), as illustrated by the following M code:
set deffn="GTM_JOBEXAMINE.ZSHOW_DMP_"_$JOB_"_"_<cntr>
set filespec=$zparse(expr1,"",deffn)
The $ZJOBEXAM()does not trigger error processing except when there is a
problem storing its return value, so no error is reported to the process
until after any dump is complete. In the event of any error encountered
during the $ZJOBEXAM(), GT.M sends an appropriate message to operator log
facility and returns control to the caller. Note that this special error
handling applies only to the $ZJOBEXAM(), and is not a property of the
$ZINTERRUPT interrupt handler, which uses $ZJOBEXAM() by default.
$ZJOBEXAM() dump files contain the context of a process at the time the
function executes. Placement and management of these files should consider
their potential size and security implications.
3 Examples
Examples
Example:
GTM>set x=$zjobexam()
GTM>write x
/home/gtmuser1/.fis-gtm/V5.4-002B_x86/r/GTM_JOBEXAM.ZSHOW_DMP_28760_1
GTM>set x=$zjobexam("test.file")
GTM>write x
/home/gtmuser1/.fis-gtm/V5.4-002B_x86/r/test.file
GTM>
Shows default file name and type of the files created containing the zshow
dump information and the difference when the name and type are specified.
2 $ZJustify()
$ZJustify()
Returns a formatted and fixed length byte sequence.
The format for the $ZJUSTIFY() function is:
$ZJ[USTIFY](expr,intexpr1[,intexpr2])
3 Examples
Examples
Example:
GTM>write "123456789012345",! write $zjustify("***",15),!,$zjustify("***",5)
123456789012345
***
***
GTM>
This example uses $ZJUSTIFY() to display the sequence of octets
represented by "***" in fields of 15 space octets and 5 space octets.
Because the byte length of "***" is 9, it exceeds 5 spaces, the result
overflows the specification.
2 $ZLength()
$ZLength()
Returns the length of a sequence of octets measured in bytes, or in
"pieces" separated by a delimiter specified by one of its arguments.
The format for the $ZLENGTH() function is:
$ZL[ENGTH](expr1[,expr2])
3 Examples
Examples
Example:
GTM>write $zlength("************")
36
GTM>
This uses $ZLENGTH() to WRITE the length in bytes of the sequence of
octets "************".
Example:
GTM>set x="*"_$zchar(63)_"*"_$zchar(63)_"*"
GTM>write $zlength(x,$zchar(63))
3
GTM>
This uses $ZLENGTH() to WRITE the number of pieces in a sequence of
octets, as delimited by the byte code $ZCHAR(63).
Example:
GTM>set x=$zchar(63)_"*"_$zchar(63)_"*"_$zchar(63)_"*"_$zchar(63)"
GTM>write $zlength(x,$zchar(63))
5
GTM>
This also uses $ZLENGTH() to WRITE the number of pieces in a sequence of
octets, as delimited by byte code $ZCHAR(63). Notice that GT.M counts both
the empty beginning and ending pieces in the string because they are both
delimited.
2 $ZMessage()
$ZMessage()
Returns a message string associated with a specified status code .
The format for the $ZMESSAGE function is:
$ZM[ESSAGE](intexpr)
$ZMESSAGE() provides a tool for examining the message and/or mnemonic
associated with a particular message code as reported in $ZSTATUS.
The $ZSTATUS Intrinsic Special Variable holds the message code and the
message of the last non-Direct Mode GT.M error. For more information on
$ZSTATUS, refer "Intrinsic Special Variables".
3 Examples
Examples
Example:
GTM>write $zmessage(36)
Interrupted system call
GTM>
This uses $ZMESSAGE() to display the message string corresponding to code
36.
2 $ZPARSE()
$ZPARSE()
Expands a file name to a full pathname and then returns the full pathname
or one of its fields (directory, name, or extension).
The format for the $ZPARSE function is:
$ZPARSE(expr1[,expr2[,expr3[,expr4[,expr5]]]])
$ZPARSE() provides a tool for verifying that a file name is syntactically
correct, for examining specific fields of a file name, and for filling in
missing pieces in a partial specification based on a hierarchy of
defaults. For information about determining whether a file exists, see
"$ZSEARCH()".
$ZPARSE() arguments, after the first, are optional. If you use no other
arguments, a single argument is sufficient. However, if you use selected
arguments $ZPARSE() requires that null strings ("") be filled in for the
unspecified arguments.
The acceptable keywords for the second argument are:
"DIRECTORY": Directory name
"NAME": File name (excluding file extension)
"TYPE": File type extension
The keywords may be entered in either upper or lower case. Variables that
evaluate to these strings and indirection are acceptable for argument two.
When the keywords themselves appear as string literals, they must be
enclosed in quotation marks (" ").
The following guidelines must be followed in constructing arguments one,
three and four:
o Directory specifications must end in a slash; anything after the final
slash in the directory specification is assumed to be part of the name
specification.
o A file name with an extension must include at least one character to
the left of the period (.). Thus, "/user/.login" refers to the file
named ".login", while "/usr/taxes.c" refers to a file named "taxes"
with the extension "c". If a file name includes more than one period,
the extension includes all letters to the right of the rightmost
period.
The keywords for the fifth argument $ZPARSE() are:
NULL (""): Returns a full file-specification or device
"SYNTAX_ONLY": Disables checking for the existence of the directory or
device.
3 Examples
Examples
Example:
GTM>write $zparse("test","","/usr/work/","dust.lis")
/usr/work/test.lis
GTM>
This uses $ZPARSE() to demonstrate defaulting using the third and fourth
arguments. The result gets the directory field from the third expression,
the name from the first expression, and the type from the fourth
expression.
Example:
GTM>r!,"file :",f w ?20,$zparse(f,"directory")
file: test.list /usr/work/
GTM>
This uses $ZPARSE() to display the directory for the file name entered as
input at the prompt file: , in this case, the current working directory.
Example:
$ cd /usr/work/me
$ $gtm
GTM>write $zparse("test","","x.list","y.c")/usr/work/me/test.lis
GTM>write $zparse("test","","/usr/work/","/dev/y.c")/usr/work/test.c
GTM>write $zparse("test","","/usr/work","/dev/y.c")/usr/test.c
GTM>
This example illustratest the use of the third and fourth arguments to
$ZPARSE(). In the first statement, the first argument has no directory or
extension field, so $ZPARSE() substitutes the extension field from the
third argument. Since neither the third nor fourth argument specifies a
directory, and because the fourth argument does not contain any fields
that are not present in the third argument, the fourth argument is not
used.
In the second statement, the first argument to $ZPARSE() is again missing
both the directory and extension. In this instance, $ZPARSE() uses the
directory specified in the third argument and, becuase neither the first
nor third argument specifies a file extension, $ZPARSE() uses the file
extension from the fourth argument.
In the third statement, because "/usr/work" does not end with a backward
slash (/), $ZPARSE() interprets the substring "work" as a file name. Then,
$ZPARSE() substitutes "/usr/" for the directory missing in the first
argument and substitutes ".c" from the fourth argument for the extension
missing from both the first and third arguments.
Example:
$ cd /usr/work/me
$ /usr/lib/fis-gtm/V5.4-002B_x86/gtm
GTM>For i="DIRECTORY","NAME","TYPE","" Write $ZPARSE("test.m",i),!
/usr/work/me/
test
.m
/usr/work/me/test.m
GTM>
This example illustrates the output produced for each of the possible
values for the second argument.
2 $ZPiece()
$ZPiece()
Return a sequence of bytes delimited by a specified byte sequence made up
of one or more bytes.
The format for the $ZPIECE function is:
$ZP[IECE](expr1,expr2[,intexpr1[,intexpr2]])
3 Examples
Examples
Example:
GTM>for i=0:1:3 write !,$zpiece("*"_$zchar(64)_"*",$zchar(64),i),"|"
|
*|
*|
|
GTM>
This loop displays the result of $ZPIECE(), specifying $ZCHAR(64) as a
delimiter, a piece position "before," first and second, and "after" the
sequence of octets.
Example:
GTM>for i=-1:1:3 write !,$zpiece("*"_$zchar(64)_"*",$zchar(64),i,i+1),"|"
|
*|
*@*|
*|
|
GTM>
This example is similar to the previous example except that it displays
two pieces on each iteration. Notice the delimiter () in the middle of the
output for the third iteration, which displays both pieces.
Example:
For p=1:1:$ZLength(x,"/") Write ?p-1*10,$ZPiece(x,"/",p)
This loop uses $ZLENGTH() and $ZPIECE() to display all the pieces of x in
columnar format.
Example:
GTM>Set $piece(x,$zchar(64),25)="" write x
***@@@@@@@@@@@@@@@@@@@@@@@@
This SETs the 25th piece of the variable x to null, with delimiter
$ZCHAR(64). This produces a byte sequence of 24 at-signs (@) preceding the
null.
2 $ZPEEK()
$ZPEEK()
Provides a way to examine memory in the current process address space. It
is intended as a tool to make it more convenient for FIS to access
information in the address space of processes more efficiently than by
calling out to external functions. It is documented here for completeness.
While FIS normally maintains stability of GT.M functionality from release
to release, this function is not designed for non-FIS usage, and FIS may
change or eliminate this function at any time.
The $ZPEEK() function returns the contents of the memory requested as a
string depending on the requested (or defaulted) formatting.
The format of the $ZPEEK() function is:
$ZPEEK("mnemonic[:argument]",offset,length[,format])
o mnemonic specifies the memory area $ZPEEK() is to access. Some
mnemonics have arguments separated from the mnemonic by a colon (":").
The mnemonics are case independent. Possible mnemonics, their possible
abbreviations and their arguments are:
o CSA[REG] - returns a value from the sgmnt_addrs (process private)
control block. Takes a case independent region name as an
argument.
o FH[REG] - returns a value from the sgmnt_data (shared file
header) control block. Takes a case independent region name as an
argument.
o GDR[REG] - returns a value from the gd_region (process private)
control block. Takes a case independent region name as an
argument.
o GLF[REPL] - returns a value from the jnlpool.gtmsrc_lcl_array[n]
control block. Takes a numeric index (n) as an argument.
o GRL[REPL] - returns a value from the recvpool.gtmrecv_local
control block. No argument allowed. Only available when run on a
non-primary instance.
o GSL[REPL] - returns a value from the
jnlpool.gtmsource_local_array[n] control block. Takes a numeric
index (n) as an argument.
o JPC[REPL] - returns a value from the jnlpool.jnlpool_ctl control
block. No argument allowed.
o NL[REG] - returns a value from the node_local (shared) control
block. Takes a case independent region name as an argument.
o NLREPL - returns a value from the node_local (shared) control
block associated with replication. No argument allowed.
o PEEK - returns a value based on the supplied argument. Argument
is the base address of whatever is being fetched in 0xhhhhhhh
format where the h's are hex digits.
o RIH[REPL] - returns a value from the jnlpool.repl_inst_filehdr
control block. No argument allowed.
o RPC[REPL] - returns a value from the recvpool.recvpool_ctl
control block. No argument allowed. Only available when run on a
non-primary instance.
o UHC[REPL] - returns a value from the recvpool.upd_helper_ctl
control block. No argument allowed. Only available when run on a
non-primary instance.
o UPL[REPL] - returns a value from the recvpool.upd_proc_local
control block. No argument allowed. Only available when run on a
non-primary instance.
o offset (first integer expression) is a numeric value that specifies
the offset from the address supplied or implied by the the mnemonic
and argument. Specifying a negative offset results in a BADZPEEKARG
error. Specifying too large an offset such that unavailable memory is
specified results in a BADZPEEKRANGE error.
o length (second integer expression) is a numeric value that specifies
the length of the field to be fetched. Specifying a negative legnth
results in a BADZPEEKARG error. Specifying a length that exceeds the
maximum string length results in a MAXSTRLEN error. Specifying too
large a length such that unavailable memory is specified results in a
BADZPEEKRANGE error.
o format is an optional single case independent character formatting
code for the retrieved data. The formatting codes are:
o C : returns a character representations of the memory locations;
this is the DEFAULT if the fourth argument is not specified.
o I : returns a signed integer value - negative values have a
preceding minus sign (-); the length can be 1, 2, 4, or 8 bytes.
o U : returns an unsigned integer value - all bits are part of the
numeric value; the length can be 1, 2, 4, or 8 bytes.
o S : returns a character representation of the memory locations
and the first NULL character found terminates the returned
string; that is: the specified length is a maximum.
o X : returns a hexadecimal value as 0xXXXXXX where XXXXXX is twice
the specified length in bytes, so requested length 1 returns 0xXX
and length 4 returns 0xXXXXXXXX; the length can be 1, 2, 4, or 8
bytes.
o Z : returns a hexadecimal representation of the memory locations
as 'X' does, without regard to endianness, and with no length
restriction other than max string length.
o $ZPEEK() function generates an UNDEF error when VIEW UNDEF is not
set and format parameter is specified but is undefined.
**Note**s
o $ZPEEK() has no UTF-8 checking. It is possible for values returned by
the 'C' and 'S' codes to have invalid UTF-8 values in them. Take care
when processing values obtained by these codes to either use "VIEW
NOBADCHAR" when dealing with such values and/or use the $Zxxx()
flavors of functions like $ZPIECE(), $ZEXTRACT(),etc which also do not
raise BADCHAR errors when encountering invalid UTF-8 encoded strings.
o Note that $ZPEEK() with 8 byte numeric formatting can return numeric
string values that exceed GT.M's current limit of 18 digits of
precision. If the values are used as strings, the extra digits are
preserved, but if used arithmetically, the lower precision digits can
be lost.
o When values from replication structures are requested and the
structures are not available due to replication not running or, in the
case of the gtmrecv.* control block base options, if not running on a
non-primary instance where the gtmrecv.* control are available, a
ZPEEKNOREPLINFO error is raised.
2 $ZPrevious()
$ZPrevious()
The $ZPREVIOUS function returns the subscript of the previous local or
global variable name in collation sequence within the array level
specified by its argument. When $ZPREVIOUS() has an unsubscripted
argument, it returns the previous unsubscripted local or global variable
name in collating sequence.
The $ZPREVIOUS function provides compatibility with some other M
implementations. The M Development Committee chose to implement this
functionality with the optional second -1 argument of $ORDER(). Therefore,
when a design requires this functionality $ORDER() has the advantage over
$ZPREVIOUS of being part of the M standard.
The format for the $ZPREVIOUS function is:
$ZP[REVIOUS](glvn)
$ZPREVIOUS() is equivalent to $ORDER() with a second argument of -1.
2 $ZSOCKET()
$ZSOCKET()
Returns information about a SOCKET device and its attached sockets. The
format of the $ZSOCKET() function is:
$ZSOCKET(expr1,expr2[,[expr3][,expr4]])
o The first expression specifies the SOCKET device name; an empty string
returns the same result as the current device ($IO). If the first
expression is not specified, $ZSOCKET() returns information about
sockets in the socketpool. Specifying a device other than a SOCKET
device for the $ZSOCKET() function produces a ZSOCKETNOTSOCK error.
o The second expression specifies a keyword identifying the type of
information returned and the optional third expression usually
specifies the index (starting at zero) of a socket attached to the
device; if the index is outside the range of attached sockets,
$ZSOCKET() returns an empty string. If the third expression is not
specified, $ZSOCKET() returns information about the current socket.
Using an invalid keyword produces a ZSOCKETATTR error. The fourth
expression specifies an individual delimiter when the second
expression specifies DELIMITER. For more information, see the
following table. Note that changes to the socket collection for a
SOCKET device using OPEN, CLOSE, USE :ATTACH, or USE :DETACH may
change the index for a socket.
+------------------------------------------------------------------------+
| Keyword | Arguments | Returns |
|---------------+------------+-------------------------------------------|
| CURRENTINDEX | | The index (starting at zero) of the |
| | | current socket for the SOCKET device. |
|---------------+------------+-------------------------------------------|
| | | If only index is specified, the number of |
| | | delimiters. |
| DELIMITER | index[, | |
| | delimiter] | If delimiter is also specified, selects |
| | | which delimiter to return. The first |
| | | delimiter is zero. |
|---------------+------------+-------------------------------------------|
| DESCRIPTOR | index | The OS socket descriptor for the socket. |
|---------------+------------+-------------------------------------------|
| | | LISTEN, CONNECT, ACCEPTED, PRINCIPAL, or |
| | | PASSED |
| | | |
| HOWCREATED | index | PRINCIPAL indicates that the socket is |
| | | the $PRINCIPAL of the process. |
| | | |
| | | PASSED indicates a socket passed by WRITE |
| | | /ACCEPT. |
|---------------+------------+-------------------------------------------|
| INDEX | handle | The current index of the socket named by |
| | | handle. |
|---------------+------------+-------------------------------------------|
| IOERROR | index | 1 if IOERROR=TRAP otherwise 0. |
|---------------+------------+-------------------------------------------|
| | | The address of the local side of the |
| LOCALADDRESS | index | socket. For TCP sockets: the IPv4 or IPv6 |
| | | numeric address. For LOCAL socket: the |
| | | path. |
|---------------+------------+-------------------------------------------|
| LOCALPORT | index | The numeric port of the local side of a |
| | | TCP socket. |
|---------------+------------+-------------------------------------------|
| | | The value of the MOREREADTIME device |
| MOREREADTIME | index | parameter if it was specified, otherwise |
| | | an empty string. |
|---------------+------------+-------------------------------------------|
| NUMBER | | The number of sockets in the SOCKET |
| | | device. |
|---------------+------------+-------------------------------------------|
| | | If the socket was created from a |
| PARENT | index | LISTENing socket: the handle of the |
| | | LISTENing socket. |
|---------------+------------+-------------------------------------------|
| PROTOCOL | index | TCP, TCP6, or LOCAL |
|---------------+------------+-------------------------------------------|
| | | The address of the remote side of the |
| REMOTEADDRESS | index | socket. For TCP sockets: the IPv4 or IPv6 |
| | | numeric address. For LOCAL socket: the |
| | | path. |
|---------------+------------+-------------------------------------------|
| REMOTEPORT | index | The numeric port of the remote side of a |
| | | TCP socket. |
|---------------+------------+-------------------------------------------|
| SOCKETHANDLE | index | The handle for the selected socket. |
|---------------+------------+-------------------------------------------|
| STATE | index | One of LISTENING, CONNECTED, BOUND, or |
| | | CONNECTINPROGRESS |
|---------------+------------+-------------------------------------------|
| ZBFSIZE | index | Size of the GT.M buffer in bytes. |
|---------------+------------+-------------------------------------------|
| ZFF | index | The value of the ZFF device parameter. |
|---------------+------------+-------------------------------------------|
| ZIBFSIZE | index | Size of the OS buffer in bytes |
| | | (SO_RCVBUF). |
|---------------+------------+-------------------------------------------|
| ZDELAY | index | 1 if Nagle algorithm enabled, otherwise |
| | | 0. |
+------------------------------------------------------------------------+
2 $ZSYSLOG()
$ZSYSLOG()
Sends its string parameter to the system log and always returns TRUE (1).
The text appears in the syslog with the same format as any other GT.M
syslog message (that is, in the user.info log with GTM-MUMPS[pid]" or
"GTM-MUPIP[pid]" prefix along with instance information where
appropriate). The format of the $ZSYSLOG function is:
$ZSYSLOG(expr)
2 $ZQGBLMOD()
$ZQGBLMOD()
The $ZQGBLMOD function enables an application to determine whether it can
safely apply a lost transaction to the database. A lost transaction is a
transaction that must be rolled off a database to maintain logical
multisite consistency.
The format for the $ZQGBLMOD function is:
$ZQGBLMOD(gvn)
$ZQGBLMOD function produces an error if you submit an argument that is not
a global variable name.
Internally, $ZQGBLMOD (gvn) compares the GT.M transaction number in the
database block in which the global variable name is stored with the value
in the Zqgblmod_Trans (and Zqgblmod_Seqno) fields stored in the database
file header.
For example, if x is the transaction number of the level-0 database block
in which gvn resides, and y is the value of Zqgblmod_Seqno of region reg
containing gvn, then the following is true:
If a transaction is a lost transaction that has been rolled back and it is
determined that for all the M globals set and killed in the transaction
$ZQGBLMOD() is zero (0), it is probably safe to apply the updates
automatically. However, this determination of safety can only be made by
the application designer and not by GT.M. If the $ZQGBLMOD() is one (1)
for any set or kill in the transaction, it is not safe to apply the
update.
**Note**
The test of $ZQGBLMOD() and applying the updates must be encapsulated
inside a GT.M transaction.
Another approach to handling lost transactions would be to store in the
database the initial message sent by a client, as well as the outcome and
the response, and to reprocess the message with normal business logic. If
the outcome is the same, the transaction can be safely applied.
**Note**
If restartable batch operations are implemented, lost batch transactions
can be ignored since a subsequent batch restart will process them
correctly.
2 $ZSEARCH()
$ZSEARCH()
The $ZSEARCH function attempts to locate a file matching the specified
file name. If the file exists, it returns the file name; if the file does
not exist, it returns the null string.
The format for the $ZSEARCH function is:
$ZSEARCH(expr[,intexpr])
$ZSEARCH() provides a tool for verifying that a file exists.
**Note**
You can call the POSIX stat() function to access metadata. The optional
GT.M POSIX plug-in packages the stat() function for easy access from M
application code.
3 Examples
Examples
Example:
GTM>write $zsearch("data.dat")
/usr/staff/ccc/data.dat
GTM>
This uses $ZSEARCH() to display the full file path name of "data.dat" in
the process current default directory.
Example:
GTM>set x=$zsearch("*.c")
GTM>for set x=$zsearch("*.m") quit:x="" write !,$zparse(x,"NAME")
This FOR loop uses $ZSEARCH() and $ZPARSE() to display M source file names
in the process current working directory. To ensure that the search starts
at the beginning, the example resets the context by first searching with a
different argument.
2 $ZSIGPROC()
$ZSIGPROC()
Sends a signal to a process. The format for the $ZSIGPROC function is:
$ZSIGPROC(expr1,expr2)
**Caution**
Although $ZSIGPROC() may work today as a way to invoke the asynchronous
interrupt mechanism of GT.M processes to XECUTE $ZINTERRUPT because the
underlying mechanism uses the POSIX USR1 signal, FIS reserves the right to
change the underlying mechanism to suit its convenience and sending a
POSIX USR1 may cease to work as a way to invoke the asynchronous interrupt
mechanism. Use MUPIP INTRPT as the supported and stable API to invoke the
asynchronous interrupt mechanism.
3 Examples
Examples
Example:
GTM>job ^Somejob
GTM>set ret=$>mposix.signalval("SIGUSR1",.sigusr1) zwrite
ret=0
sigusr1=10
GTM>write $zsigproc($zjob,sigusr1)
0
GTM>
This example sends the SIGUSR1 signal to the pid specified by $zjob.
2 $ZSUBstr()
$ZSUBstr()
Returns a properly encoded string from a sequence of bytes.
$ZSUB[STR] (expr ,intexpr1 [,intexpr2])
3 Examples
Examples
Example:
GTM>write $ZCHSET
M
GTM>set char1="a" ; one byte character
GTM>set char2="c,"; two-byte character
GTM>set char3="*"; three-byte character
GTM>set y=char1_char2_char3
GTM>write $zsubstr(y,1,3)=$zsubstr(y,1,5)
0
With character set M specified, the expression
$ZSUBSTR(y,1,3)=$ZSUBSTR(y,1,5) evaluates to 0 or "false" because the
expression $ZSUBSTR(y,1,5) returns more characters than $ZSUBSTR(y,1,3).
Example:
GTM>write $zchset
UTF-8
GTM>set char1="a" ; one byte character
GTM>set char2="c,"; two-byte character
GTM>set char3="*"; three-byte character
GTM>set y=char1_char2_char3
GTM>write $zsubstr(y,1,3)=$zsubstr(y,1,5)
1
For a process started in UTF-8 mode, the expression
$ZSUBSTR(y,1,3)=$ZSUBSTR(y,1,5) evaluates to 1 or "true" because the
expression $ZSUBSTR(y,1,5) returns a string made up of char1 and char2
excluding the three-byte char3 because it was not completely included in
the specified byte-length.
In many ways, the $ZSUBSTR() function is similar to the $ZEXTRACT()
function. For example, $ZSUBSTR(expr,intexpr1) is equivalent to
$ZEXTRACT(expr,intexpr1,$L(expr)). Note that this means when using the M
character set, $ZSUBSTR() behaves identically to $EXTRACT() and
$ZEXTRACT(). The differences are as follows:
* $ZSUBSTR() cannot appear on the left of the equal sign in the SET
command where as $ZEXTRACT() can.
* In both the modes, the third expression of $ZSUBSTR() is a byte,
rather than character, position within the first expression.
* $EXTRACT() operates on characters, irrespective of byte length.
* $ZEXTRACT() operates on bytes, irrespective of multi-byte character
boundaries.
* $ZSUBSTR() is the only way to extract as valid UTF-8 encoded
characters from a byte string containing mixed UTF-8 and non UTF-8
data. It operates on characters in Unicode so that its result does not
exceed the given byte length.
2 $ZTRanslate()
$ZTRanslate()
Returns a byte sequence that results from replacing or dropping bytes in
the first of its arguments as specified by the patterns of its other
arguments.
The format for the $ZTRANSLATE() function is:
$ZTR[ANSLATE](expr1[,expr2[,expr3]])
The $ZTRANSLATE() algorithm can be understood as follows:
3 Examples
Examples
Example:
GTM>set hiraganaA=$char(12354) ; $zchar(227,129,130)
GTM>set temp1=$zchar(130)
GTM>set temp2=$zchar(140)
GTM>set tr=$ztranslate(hiraganaA,temp1,temp2)
GTM>w $ascii(tr)
12364
GTM>
In the above example, $ZTRANSLATE() replaces byte $ZCHAR(130) in first
expression and matching the first (and only) byte in the second expression
with byte $ZCHAR(140) - the corresponding byte in the third expression.
2 $ZTRIgger()
$ZTRIgger()
Examine or load trigger definition. The format of the $ZTRIGGER() function
is:
$ZTRIgger(expr1[,expr2])
3 Examples_of_$ZTRIGGER()
Examples of $ZTRIGGER()
Example:
GTM>set X=$ztrigger("S")
GTM>
This example displays the current trigger definitions stored in the
database.
GTM>set X=$ztrigger("i","+^Acct(sub=:) -command=set -xecute=""set ^X($ztvalue)=sub""")
GTM>
This example adds a trigger definition for the first level node of ^Acct.
Example:
GTM>set trigstr="+^a -commands=S -xecute=<<"_$c(10)_" do ^twork1"_$c(10)_" do ^twork2"_$c(10) write $ztrigger("item",trigstr)
This example demonstrates the usage of the
$ztrigger("ITEM",<multi-line-trigger-definition>> where <<denotes the
definition of a multi-line -XECUTE string and $c(10) to denote the newline
separator. Unlike the $ztrigger("FILE") form,
$ztrigger("ITEM",<multi-line-trigger-definition>> does not require trigger
definition to terminate with >>.
Example:
GTM>write $ztrigger("file","agbl.trg")
1
GTM>
This example is equivalent to the previous $ztrigger("ITEM") example. In
this example, agbl.trg contains the following multi-line trigger
definition:
+^a -commands=S -xecute=<<
do ^twork1
do ^twork2
>>
Unlike $ztrigger("ITEM"), $ztrigger("FILE") usages require the trigger
definition to terminate with >>
2 $ZTRNLNM()
$ZTRNLNM()
The $ZTRNLNM function returns the value of an environment variable.The
$ZTRNLNM function is analogous to the DCL Lexical function F$TRNLNM on
OpenVMS.
**Note**
$ZTRNLNM() does not perform iterative translation.
The format for the $ZTRNLNM function is:
$ZTRNLNM(expr1[,expr2[,expr3[,expr4[,expr5[,expr6]]]]])
expr1 specifies the environment variable whose value needs to be returned.
expr2 to expr5 are OpenVMS-related expressions that specify logical name
table(s), index (numbered from 0), initial mode of the look-up, and a
value indicating whether the look-up is case sensitive. To ensure
interoperability between UNIX and OpenVMS versions, $ZTRNLNM() on UNIX
accepts these expressions and ignores them.
expr6 specifies any one of the following keywords:
+-----------------------------------------------------+
| ITEM KEYWORD | DATA RETURNED |
|--------------+--------------------------------------|
| FULL | Returns the translation. |
|--------------+--------------------------------------|
| LENGTH | Length of the return value in bytes. |
|--------------+--------------------------------------|
| VALUE | Returns the translation. |
+-----------------------------------------------------+
3 Examples
Examples
Example:
GTM>write $ztrnlnm("gtm_dist","","","","","VALUE")
/usr/lib/fis-gtm/V6.0-000_x86_64/utf8
GTM>
This uses $ZTRNLNM() to display the translation value for gtm_dist.
2 $ZWidth()
$ZWidth()
Returns the numbers of columns required to display a given string on the
screen or printer. The format of the $ZWIDTH() function is:
$ZW[IDTH] (expr)
**Note**
The ZWIDTH() function triggers a run-time error if it encounters a
malformed byte sequence irrespective of the setting of "BADCHAR".
With character set UTF-8 specified, the $ZWIDTH() function uses the ICU's
glyph-related conventions to calculate the number of columns required to
represent the expression.
3 Examples
Examples
Example:
GTM>set NG=$char($$FUNC^%HD("200B"))
GTM>set S=$char(26032)_NG_$CHAR(26033)
GTM>W $ZWidth(STR)
4
GTM>
In the above example, the local variable NG contains a non-graphic
character which does not display between two double-width characters in
Unicode.
Example:
GTM>write $zwidth("The rain in Spain stays mainly in the plain.")
44
GTM>set A="************"
GTM>write $length(A)
12
GTM>write $zwidth(A)
24
In the above example, the $ZWIDTH() function returns 24 because each
character in A occupies 2 columns when they are displayed on the screen or
printer.
2 $ZWRite()
$ZWRite()
Takes a single expression argument and returns that expression with the
non-graphic characters represented in the $CHAR() format used by the
ZWRITE command. Note that the non-graphic characters differ between M mode
and UTF-8 mode. The format of the $ZWRITE function is:
$ZWRITE(expr)
1 ISV
ISV
This chapter describes the M Intrinsic Special Variables implemented in
GT.M. All entries starting with the letter Z are GT.M additions to the
ANSI standard Intrinsic Special Variables. None of the Intrinsic Special
Variables are case sensitive.
M Intrinsic Special Variables start with a single dollar sign ($). GT.M
provides such variables for program examination. In some cases, the
Intrinsic Special Variables may be set to modify the corresponding part of
the environment.
**Note**
None of the Intrinsic Special Variables can be KILLed. SETting or NEWing
is generally not allowed, but is specifically noted in the descriptions of
those that do.
2 $Device
$Device
$D[EVICE] reflects the status of the current device. If the status of the
device does not reflect any error-condition, the value of $DEVICE, when
interpreted as a truth-value is 0 (FALSE). If the status of the device
reflect any error-condition, the value of $DEVICE, when interpreted as a
truth-value is 1 (TRUE).
**Note**
The initial value of $DEVICE is implementation dependant. However, if the
initial value of $IO is the empty string, then the initial value of
$DEVICE is also empty string.
$DEVICE gives status code and meaning, in one access:
Example:
1,Connection reset by peer
The above message is displayed on the server side when the socket device
is closed on the client side.
2 $ECode
$ECode
$EC[ODE] contains a list of error codes for "active" errors -the error
conditions which are not yet resolved. If there are no active errors,
$ECODE contains the empty string. Whenever an error occurs, a code for
that error is appended to the value of $ECODE in such a way that the value
of $ECODE always starts and ends with a comma.
The value of $ECODE can be SET, and when it is set to a non-NULL value,
error processing starts.
List of codes for $ECODE start with comma seperated by commas. A code
starts with "M", "U", or "Z", with rest numeric. "M" codes are assigned by
MDC (MUMPS Development Committee), "U" by application (programmers), and
"Z" codes by MUMPS implementors (in this case GT.M).
An error always has a GT.M specified code and many errors also have an
ANSI Standard code. The complete list of standardized error codes can be
referenced from GT.M Message and Recovery Procedures Reference Manual
version 4.3 and onwards.
IF $ECODE[",M61," WRITE "Undefined local variable"
**Note**
The leftmost character of the value of $ECODE is always a comma. This
means that every error code that is stored in $ECODE is surrounded by
commas. If $ECODE was to contains the error code without the commas (that
is, "M61"), the variable would check for subset "M6" as well. Thus, it is
recommended that you include the commas in the value to check. For
example; check whether $ECODE contains ",M61,".
$ECODE can be SET but not NEW'd. When $ECODE is set to the empty string ("
"), error handling becomes "inactive" and therefore QUIT does not trigger
additional error handling.
When $ECODE is not set to the empty string, M error handling is active,
which also affects behavior in some aspects of $STACK.
2 $EStack
$EStack
$ES[TACK] contains an integer count of the number of M virtual machine
stack levels that have been activated and not removed since the last time
$ESTACK was NEW'd.
A NEW $ESTACK saves the value of current $ESTACK and then sets its value
to zero (0). If $ESTACK has not been NEW'd in the current execution path,
$ESTACK=$STACK.
SET $ETRAP="QUIT:$ESTACK GOTO LABEL^ROUTINE"
$ESTACK maybe used as a flag to indicate error traps invoked in particular
stack levels needed to perform some different action(s). $ESTACK can be
most useful in setting up a layered error trapping mechanism.
**Note**
GT.M does not permit $ESTACK to be SET, however $ESTACK can be NEWed.
2 $ETrap
$ETrap
$ET[RAP] contains a string value that GT.M invokes when an error occurs
during routine execution. When a process is initiated, but before any
commands are processed, the value of $ETRAP is empty string.
The value of this variable is the M[UMPS] code that gets executed when an
error occurs.
SET $ETRAP="QUIT:$ESTACK GOTO LABEL^ROUTINE"
The value of $ETRAP is changed with the SET command. Changing the value of
$ETRAP with the SET command initiates a new trap; it does not save the old
trap.
$ETRAP may also appear as an argument to an inclusive NEW command. NEW
$ETRAP causes GT.M to stack the active condition handler's ($ETRAP or
$ZTRAP) old value. If $ZTRAP is the active condition handler, the NEW
implicitly sets the current $ZTRAP value to null. NEW leaves the $ETRAP
unchanged regardless of the previously active condition handler. The NEW
command puts the target ISV in control for error handling.
For more examples of the use of special variable $ETRAP, see the function
$STACK().
2 $Horolog
$Horolog
$H[OROLOG] contains a string value specifying the number of days since "31
December, 1840," and the number of seconds since midnight of the current
day, separated by a comma (,).
At midnight, the piece of the string following the comma resets to zero
(0) and the piece preceding the comma increments by one (1). GT.M does not
permit the SET command to modify $HOROLOG.
Example:
GTM>Write $HOROLOG
Produces the result 58883,55555 at 3:25:55 pm on 20 March, 2002.
For further information on formatting $HOROLOG for external use, refer to
"$ZDate()".
2 $IO
$IO
$I[O] contains the name of the current device specified by the last USE
command. The M standard does not permit the SET command to modify $IO. USE
0 produces the same $IO as USE $P[RINCIPAL], but $P is the preferred
construct.
2 $Job
$Job
$J[OB] the current process identifier.
GT.M uses the decimal representation of the current process identifier
(PID) for the value of $JOB. $JOB is guaranteed to be unique for every
concurrently operating process on a system. However, operating systems
reuse PIDs over time. GT.M does not permit the SET command to modify $JOB.
Example:
LOOP0 for set itm=$order(^tmp($J,itm)) quit:itm="" do LOOP1
This uses $J as the first subscript in a temporary global to insure that
every process uses separate data space in the global ^tmp.
2 $Key
$Key
$K[EY] contains the string that terminated the most recent READ command
from the current device (including any introducing and terminating
characters). If no READ command was issued to the current device or if no
terminator is used, the value of $KEY is an empty string. However, when
input is terminated by typing a function key, the value of $KEY is equal
to the string of characters that is transmitted by that function key.
The effect of a READ *glvn on $KEY is unspecified.
For terminals, $KEY and $ZB both have the terminator.
For SOCKET:
$KEY contains the socket handle and the state information of the current
SOCKET device after certain I/O commands.
After a successful OPEN or USE with the LISTEN deviceparameter, $KEY
contains for TCP sockets:
"LISTENING|<socket_handle>|<portnumber>"
and for LOCAL sockets:
"LISTENING|<socket_handle>|<address>"
After a successful OPEN or USE with the CONNECT device parameter or when
GT.M was started with a socket as the $PRINCIPAL device, $KEY contains:
"ESTABLISHED|<socket handle>|<address>"
When WRITE /WAIT selects an incoming connection, $KEY contains:
"CONNECT|<socket_handle>|<address>"
When WRITE /WAIT selects a socket with data available for reading, $KEY
contains:
"READ|<socket_handle>|<address>"
For TCP sockets, <address> is the numeric IP address for the remote end of
the connection. For LOCAL sockets it is the path to the socket.
For TCP LISTENING sockets, <portnumber> is the local port on which
socket_handle is listening for incoming connections. For LOCAL LISTENING
sockets, it is the path of the socket.
If the WRITE /WAIT was timed, $KEY returns an empty value if the wait
timed out or there was no established connection. $KEY only has the
selected handle, if any, immediately after a WRITE /WAIT. $KEY is also
used by other socket I/O commands such as READ which sets it to the
delimiter or bad Unicode character, if any, which terminated the read.
2 $Principal
$Principal
$P[RINCIPAL] contains the absolute pathname of the principal (initial $IO)
device. $PRINCIPAL is an MDC Type A enhancement to standard M.
Input and output for a process may come from separate devices, namely, the
standard input and output. However, the M I/O model allows only one device
to be USEd (or active) at a time. When an image starts, GT.M implicitly
OPENs the standard input and standard output device(s) and assigns the
device(s) to $PRINCIPAL. For USE deviceparameters, it is the standard
input that determines the device type.
For an image invoked interactively, $PRINCIPAL is the user's terminal. For
an image invoked from a terminal by means of a shell script, $PRINCIPAL is
the shell script's standard input (usually the terminal) and standard
output (also usually the terminal) for output, unless the shell redirects
the input or output.
GT.M provides a mechanism for the user to create a name for $PRINCIPAL in
the shell before invoking GT.M. The environment variable gtm_principal, if
defined becomes a synonym for the actual device and the value for
$PRINCIPAL. $IO holds the same value as $PRINCIPAL. $ZIO in this case,
holds the fully expanded name of the actual device.
GT.M ignores a CLOSE specifying the principal device. GT.M does not permit
the SET command to modify $PRINCIPAL.
GT.M discards reads and writes against an empty socket device (that is,
one with all sockets detached) if it is the $PRINCIPAL device.
GT.M opens /dev/null as a placeholder for a socket which used to be
associated with $PRINCIPAL via stdin when it is closed.
GT.M creates a SOCKET device for $PRINCIPAL when standard input is a LOCAL
domain socket and sets the default DELIMITER to "$C(10)" for sockets in
the device.
When $PRINCIPAL identifies a device that supports REWIND, the REWIND or
INREWIND device parameters perform a REWIND of the input and OUTREWIND
performs a REWIND of the output.
2 $Quit
$Quit
$Q[UIT] indicates whether the current block of code was called as an
extrinsic function or as a subroutine.
If $Q[UIT] contains 1 (when the current process-stack frame is invoked by
an extrinsic function), the QUIT would therefore require an argument.
**Note**
When a process is initiated, but before any commands are processed, the
value of $Q[UIT] is zero (0).
This special variable is mainly used in error-trapping conditions. Its
value tells whether the current DO level was reached by means of a
subroutine call (DO xxx) or by a function call (SET variable=$$xxx).
A typical way of exiting from an error trap is:
QUIT:$QUIT "" QUIT
**Note**
GT.M does not permit $QUIT to be SET or NEWed.
2 $Reference
$Reference
$R[EFERENCE] contains the last global reference. Until the first global
reference is made by an M program, $REFERENCE contains the empty string
(""). This way it is useful in determining if the usage of a naked
reference is valid.
A typical way of using this is:
IF $REFERENCE="" QUIT "<undefined>"
**Note**
$R[EFERENCE] being a read-only variable cannot be SET or NEW'd.
2 $STack
$STack
$ST[ACK] contains an integer value of zero (0) or greater indicating the
current level of M execution stack depth.
When a process is initiated but before any command is executed, the value
of $STACK is zero (0).
**Note**
The difference between $STACK and $ESTACK is that $ESTACK may appear as an
argument of the NEW command. NEWing $ESTACK resets its value to zero (0),
and can be useful to set up a layered error trapping mechanism.
The value of $STACK is "absolute" since the start of a GT.M. process,
whereas the value of $ESTACK is "relative" to the most recent "anchoring
point".
2 $Storage
$Storage
$S[TORAGE] contains an integer value specifying the number of free bytes
of address space remaining between the memory currently under management
by the process and the theoretical maximum available to the process.
GT.M uses memory for code (instructions) and data. If the amount of
virtual memory available to the process exceeds 2,147,483,647 bytes, it is
reported as 2,147,483,647 bytes.
Instruction space starts out with the original executable image. However,
GT.M may expand instruction space by ZLINKing additional routines.
Data space starts out with stack space that never expands, and pool space
which may expand. Operations such as opening a database or creating a
local variable may cause an expansion in pool space. GT.M expands pool
space in fairly large increments. Therefore, SETs of local variables may
not affect $STORAGE at all or may cause an apparently disproportionate
drop in its value.
Once a GT.M process adds either instruction or data space, it never
releases that space. However, GT.M does reuse process space made available
by actions such as KILLs of local variables. $STORAGE can neither be SET
or NEWed.
2 $SYstem
$SYstem
$SY[STEM] contains a string that identifies the executing M instance. The
value of $SYSTEM is a string that starts with a unique numeric code that
identifies the manufacturer. Codes are assigned by the MDC (MUMPS
Development Committee).
$SYSTEM in GT.M starts with "47" followed by a comma and the evaluation of
the environment variable gtm_sysid. If the name has no evaluation, the
value after the comma is gtm_sysid.
2 $Test
$Test
$T[EST] contains a truth value specifying the evaluation of the last IF
argument or the result of the last operation with timeout. If the last
timed operation timed out, $TEST contains FALSE (0); otherwise, it
contains TRUE (1).
$TEST serves as the implicit argument for ELSE commands and argumentless
IF commands.
M stacks $TEST when invoking an extrinsic and performing an argumentless
DO. After these operations complete with an implicit or explicit QUIT, M
restores the corresponding stacked value. Because, with these two
exceptions, $TEST reflects the last IF argument or timeout result on a
process wide basis. Use $TEST only in immediate proximity to the operation
that last updated it.
Neither $SELECT() nor post-conditional expressions modify $TEST.
M routines cannot modify $TEST with the SET command.
Example:
IF x=+x DO ^WORK
ELSE SET x=0
The ELSE statement causes M to use the value of $TEST to determine whether
to execute the rest of the line. Because the code in routine WORK may use
IFs and timeouts, this use of $TEST is not recommended.
Example:
SET MYFLG=x=+x
IF MYFLG DO ^WORK
IF 'MYFLG SET x=0
This example introduces a local variable flag to address the problems of
the prior example. Note that its behavior results in the opposite $TEST
value from the prior example.
Example:
IF x=+x DO ^WORK IF 1
ELSE SET x=0
This example uses the IF 1 to ensure that the ELSE works counter to the
IF.
2 $TLevel
$TLevel
$TL[EVEL] contains a count of executed TSTARTs that are currently
unmatched by TCOMMITs. $TLEVEL is zero (0) when there is no TRANSACTION in
progress. When $TLEVEL is greater than one (>1), it indicates that there
are nested sub-transactions in progress. Sub-transactions are always
subject to the completion of the main TRANSACTION and cannot be
independently acted upon by COMMIT, ROLLBACK, or RESTART.
$TLEVEL can be used to determine whether there is a TRANSACTION in
progress and to determine the level of nesting of sub-transactions.
M routines cannot modify $TLEVEL with SET.
Example:
IF $TLEVEL TROLLBACK
This example performs a TROLLBACK if a transaction is in progress. A
statement like this should appear in any error handler used with
transaction processing.
2 $TRestart
$TRestart
$TR[ESTART] contains a count of the number of times the current
TRANSACTION has been RESTARTed. A RESTART can be explicit (specified in M
as a TRESTART) or implicit (initiated by GT.M as part of its internal
concurrency control mechanism). $TRESTART can have values of 0 through 4.
When there is no TRANSACTION in progress, $TRESTART is zero (0).
$TRESTART can be used by the application to limit the number of RESTARTs,
or to cause a routine to perform different actions during a RESTART than
during the initial execution.
**Note**
GT.M does not permit the SET command to modify $TRESTART.
Example:
TRANS TSTART ():SERIAL
IF $TRESTART>2 WRITE !;"Access Conflict" QUIT
This example terminates the sub-routine with a message if the number of
RESTARTs exceeds 2.
2 $X
$X
$X contains an integer value ranging from 0 to 65,535, specifying the
horizontal position of a virtual cursor in the current output record. $X=0
represents the left-most position of a record or row.
Every OPEN device has a $X. However, M only accesses $X of the current
device. Therefore, exercise care in sequencing USE commands and references
to $X.
Generally, GT.M increments $X for every character written to and read from
the current device. Usually, the increment is 1, but for a process in
UTF-8 mode, the increment is the number of glyphs or codepoints (depends
on the type of device). M format control characters, write filtering, and
the device WIDTH also have an effect on $X.
$X never equals or exceeds the value of the device WIDTH. Whenever it
reaches the value equal to the device WIDTH, it gets reset to zero (0).
GT.M follows the MDC Type A recommendation and permits an M routine to SET
$X. However, SET $X does not automatically issue device commands or escape
sequences to reposition the physical cursor.
2 $Y
$Y
$Y contains an integer value ranging from 0 to 65,535 specifying the
vertical position of a virtual cursor in the current output page. $Y=0
represents the top row or line.
Every OPEN device has a $Y. However, M only accesses $Y of the current
device. Therefore, exercise care in sequencing USE commands and references
to $Y.
When GT.M finishes the logical record in progress, it generally increments
$Y. GT.M recognizes the end of a logical record when it processes certain
M format control characters, or when the record reaches its maximum size,
as determined by the device WIDTH, and the device is set to WRAP. The
definition of "logical record" varies from device to device. For an exact
definition, see the sections on each device type. Write filtering and the
device LENGTH also have an effect on $Y.
$Y never equals or exceeds the value of the device LENGTH. Whenever it
reaches the value equal to the device LENGTH, it gets reset to zero (0)
GT.M permits an M routine to SET $Y. However, SET $Y does not
automatically issue device commands or escape sequences to reposition the
physical cursor.
2 $ZA
$ZA
$ZA contains a status determined by the last read on the device. The value
is a decimal integer with a meaning determined by the device as follows:
For Terminal I/O:
0Indicating normal termination of a read operation
1: Indicating a parity error
2: Indicating that the terminator sequence was too long
9: Indicating a default for all other errors
For Sequential Disk and Tape Files I/O:
0: Indicating normal termination of a read operation
9: Indicating a failure of a read operation
For Fifos I/O:
Decimal representing $JOB (identifier) of the process that wrote the last
message the current process read
$ZA refers to the status of the current device. Therefore, exercise care
in sequencing USE commands and references to $ZA.
GT.M does not permit the SET command to modify $ZA.
For more information on $ZA, refer "Input/Output Processing".
2 $ZALlocstor
$ZALlocstor
$ZALLOCSTOR contains the number of bytes that are (sub) allocated
(including overhead) by GT.M for various activities. It provides one view
(see also $ZREALSTOR and $ZUSEDSTOR) of the process memory utilization and
can help identify storage related problems. GT.M does not permit
$ZALLOCSTOR to be SET or NEWed.
2 $ZB
$ZB
$ZB contains a string specifying the input terminator for the last
terminal READ. $ZB contains null and is not maintained for devices other
than terminals. $ZB may contain any legal input terminator, such as <CR>
(ASCII 13) or an escape sequence starting with <ESC> (ASCII 27), from zero
(0) to 15 bytes in length. $ZB contains null for any READ terminated by a
timeout or any fixed-length READ terminated by input reaching the maximum
length.
$ZB contains the actual character string, not a sequence of numeric ASCII
codes.
Example:
SET zb=$ZB FOR i=1:1:$L(zb) WRITE !,i,?5,$A(zb,i)
This displays the series of ASCII codes for the characters in $ZB.
$ZB refers to the last READ terminator of the current device. Therefore,
exercise care in sequencing USE commands and references to $ZB.
GT.M does not permit the SET command to modify $ZB.
For more information on $ZB, refer to the "Input/Output Processing"
chapter.
2 $ZCHset
$ZCHset
$ZCHSET is a read-only intrinsic special variable that takes its value
from the environment variable gtm_chset. An application can obtain the
character set used by a GT.M process by the value of $ZCHSET. $ZCHSET can
have only two values --"M", or "UTF-8".
GT.M only supports Unicode on certain platforms. On platforms where it is
not supported, the intrinsic variable $ZCHSET is always "M" ignoring the
value of the environment variable gtm_chset even if it is defined.
Example:
$ export gtm_chset=UTF-8
$ /usr/lib/fis-gtm/V6.0-001_x86/gtm
GTM>write $zchset
UTF-8
GTM>
2 $ZCMdline
$ZCMdline
$ZCM[DLINE] contains a string value specifying the "excess" portion of the
command line that invoked the GT.M process. By "excess" is meant the
portion of the command line that is left after GT.M has done all of its
command line processing. For example, a command line mumps -direct extra1
extra2 causes GT.M to process the command line upto mumps -direct and
place the "excess" of the command line, that is "extra1 extra2" in
$ZCMDLINE. $ZCMDLINE gives the M routine access to the shell command line
input.
Note that the actual user input command line might have been transformed
by the shell (for example, removing one level of quotes, filename, and
wildcard substituion, and so on.), and it is this transformed command line
that GT.M processes.
Example:
$ cat > test.m
write " $ZCMDLINE=",$ZCMDLINE,!
quit
$ mumps -run test OTHER information
$ZCMDLINE=OTHER information
$
This creates the program test.m, which writes the value of $ZCMDLINE. Note
how the two spaces specified in OTHER information in the command line gets
transformed to just one space in OTHER information in $ZCMDLINE due to the
shell's pre-processing.
Example:
$ cat foo.m
foo ; a routine to invoke an arbitrary entry with or without
parameters
;
set $etrap="" ; exit if the input isn't valid
if $length($zcmdline) do @$zcmdline quit
quit
$ mumps -run foo 'BAR^FOOBAR("hello")'
In this example, GT.M processes the shell command line up to foo and puts
the rest in $ZCMDLINE. This mechanism allows mumps -run to invoke an
arbitrary entryref with or without parameters. Note that this example
encloses the command line argument with single quotes to prevent
inappropriate expansion in Bourne-type shells. Always remember to use the
escaping and quoting conventions of the shell and GT.M to prevent
inappropriate expansion.
**Important**
Use the ^%XCMD utility to XECUTEs code from the shell command line and
return any error status (truncated to a single byte on UNIX) that the code
generates.
2 $ZCOmpile
$ZCOmpile
$ZCO[MPILE] contains a string value composed of one or more qualifiers
that control the GT.M compiler. Explicit ZLINKs and auto-ZLINKs use these
qualifiers as defaults for any compilations that they perform.
$ZCOMPILE is a read-write ISV, that is, it can appear on the left side of
the equal sign (=) in the argument to the SET command. A $ZCOMPILE value
has the form of a list of M command qualifiers each separated by a space (
).
When the environment variable gtmcompile is defined, GT.M initializes
$ZCOMPILE to the translation of gtmcompile. Otherwise GT.M initializes
$ZCOMPILE to null. Changes to the value of $ZCOMPILE during a GT.M
invocation only last for the current invocation and do not change the
value of the environment variable gtmcompile.
ZCOMPILE returns a status of 1 after any error in compilation.
When $ZCOMPILE is null, GT.M uses the default M command qualifiers
-IGNORE, -LABEL=LOWER, -NOLIST, and -OBJECT.
Example:
$ export gtmcompile="-LIST -LENGTH=56 -SPACE=2"
$ gtm
GTM>WRITE $ZCOMPILE
-LIST -LENGTH=56 -SPACE=2
GTM>SET $ZCOMPILE="-LIST -NOIGNORE"
GTM>WRITE $ZCOMPILE
-LIST -NOIGNORE
GTM>ZLINK "A.m"
GTM>HALT
$ echo $gtmcompile
-LIST -LENGTH=56 -SPACE=2
This example uses the environment variable gtmcompile to set up $ZCOMPILE.
Then it modifies $ZCOMPILE with the SET command. The ZLINK argument
specifies a file with a .m extension (type), which forces a compile. The
compile produces a listing for routine A.m and does not produce an object
module if A.m contains compilation errors. After GT.M terminates, the
shell command echo $gtmcompile demonstrates that the SET command did not
change the environment variable.
2 $ZCstatus
$ZCstatus
$ZC[STATUS] holds the value of the status code for the last compilation
performed by a ZCOMPILE command.
GT.M does not permit the SET command to modify $ZSTATUS.
2 $ZCLose
$ZCLose
Provides termination status of the last PIPE CLOSE as follows:
o -99 when the check times out
o -98 for unanticipated problems with the check
o the negative of the signal value if a signal terminated the
co-process.
If positive, $ZCLOSE contains the exit status returned by the last
co-process.
2 $ZDAteform
$ZDAteform
$ZDA[TEFORM] contains an integer value, specifying the output year format
of $ZDATE(). $ZDATEFORM can be modified using the SET command. GT.M
initializes $ZDATEFORM to the translation of the environment variable
gtm_zdate_form. If gtm_zdate_form is not defined, GT.M initializes
$ZDATEFORM to zero (0).
Refer to "Functions" and "Utility Routines" chapters in the GT.M
Programmer's Guide for more details.
Example:
GTM>WRITE $ZDATEFROM
0
GTM>WRITE $ZDATE($H)
11/15/02
GTM>SET $ZDATEFORM=1
GTM>WRITE $ZDATE($H)
11/15/2002
2 $ZDirectory
$ZDirectory
$ZD[IRECTORY] contains the string value of the full path of the current
directory. Initially $ZDIRECTORY contains the default/current directory
from which the GT.M image/process was activated.
If the current directory does not exist at the time of GT.M process
activation, GT.M errors out.
Example:
GTM>WRITE $ZDIR
/usr/tmp
GTM>SET $ZDIR=".."
GTM>WRITE $ZDIR
/usr
This example displays the current working directory and changes $ZDIR to
the parent directory.
$ZDIRECTORY is a read-write Intrinsic Special Variable, that is, it can
appear on the left side of the equal sign (=) in the argument to a SET
command. If an attempt is made to set $ZDIRECTORY to a non-existent
directory specification, GT.M issues an error and keeps the value of
$ZDIRECTORY unchanged.
At image exit, GT.M restores the current directory to the directory that
was the current directory when GT.M was invoked even if that directory
does not exist.
2 $ZEDit
$ZEDit
$ZED[IT] holds the value of the status code for the last edit session
invoked by a ZEDIT command.
GT.M does not permit the SET or NEW command to modify $ZEDIT.
2 $ZEOf
$ZEOf
$ZEO[F] contains a truth-valued expression indicating whether the last
READ operation reached the end-of-file. $ZEOF equals TRUE (1) at EOF and
FALSE (0) at other positions.
GT.M does not maintain $ZEOF for terminal devices.
$ZEOF refers to the end-of-file status of the current device. Therefore,
exercise care in sequencing USE commands and references to $ZEOF.
GT.M does not permit the SET or NEW command to modify $ZEOF.
For more information on $ZEOF, refer to the "Input/Output Processing"
chapter.
2 $ZError
$ZError
$ZE[RROR] is supposed to hold the application-specific error-code
corresponding to the GT.M error-code stored in $ECODE/$ZSTATUS.
$ZERROR contains a default value of "Unprocessed $ZERROR, see $ZSTATUS" at
process startup.
$ZERROR can be SET but not NEWed.
The mapping of a GT.M error-code to the application-specific error-code is
achieved as follows. Whenever GT.M encounters an error, $ECODE/$ZSTATUS
gets set first. It then invokes the code that $ZYERROR points to if it is
not null. It is intended that the code invoked by $ZYERROR use the value
of $ZSTATUS to select or construct a value to which it SETs $ZERROR. If an
error is encountered by the attempt to execute the code specified in
$ZYERROR, GT.M sets $ZERROR to the error status encountered. If $ZYERROR
is null, GT.M does not change the value of $ZERROR. In all cases, GT.M
proceeds to return control to the code specified by $ZTRAP/$ETRAP or
device EXCEPTION whichever is applicable.
2 $ZGbldir
$ZGbldir
$ZG[BLDIR] contains the value of the current Global Directory filename.
When $ZGBLDIR specifies an invalid or inaccessible file, GT.M cannot
successfully perform database operations.
GT.M initializes $ZGBLDIR to the translation of the environment variable
gtmgbldir. The value of the gtmgbldir environment variable may include a
reference to another environment variable. If gtmgbldir is not defined,
GT.M initializes $ZGBLDIR to null. When $ZGBLDIR is null, GT.M constructs
a file name for the Global Directory using the name $gtmgbldir and the
extension .gld in the current working directory.
$ZGBLDIR is a read-write Intrinsic Special Variable, (i.e., it can appear
on the left side of the equal sign (=) in the argument to the SET
command). SET $ZGBLDIR="" causes GT.M to assign $ZGBLDIR to the
translation of gtmgbldir if that environment variable is defined. If it is
not defined, then SET $ZGBLDIR="" causes GT.M to construct a file name
using the name $gtmgbldir.gld in the current directory. GT.M permits
$ZGBLDIR to be NEW'd. A $ZGBLDIR value may include an environment
variable.
SETting $ZGBLDIR also causes GT.M to attempt to open the specified file.
If the file name is invalid or the file is inaccessible, GT.M triggers an
error without changing the value of $ZGBLDIR.
To establish a value for $ZGBLDIR outside of M, use the appropriate shell
command to assign a translation to gtmgbldir. Defining gtmgbldir provides
a convenient way to use the same Global Directory during a session where
you repeatedly invoke and leave GT.M.
Changes to the value of $ZGBLDIR during a GT.M invocation only last for
the current invocation and do not change the value of gtmgbldir.
Example:
$ gtmgbldir=test.gld
$ export gtmgbldir
$ gtm
GTM>WRITE $zgbldir
/usr/dev/test.gld
GTM>SET $zgbldir="mumps.gld"
GTM>WRITE $zgbldir
mumps.gld
GTM>HALT
$ echo $gtmgbldir
test.gld
This example defines the environment variable gtmgbldir. Upon entering
GT.M Direct Mode, $ZGBLDIR has the value supplied by gtmgbldir. The SET
command changes the value. After the GT.M image terminates, the echo
command demonstrates that gtmgbldir was not modified by the M SET command.
$ ls test.gld
test.gld not found
$ gtm
GTM>WRITE $zgbldir
/usr/dev/mumps.gld
GTM>set $zgbldir="test.gld"
%GTM-E-ZGBLDIRACC, Cannot access global directory
"/usr/dev/test.gld". Retaining /usr/dev/mumps.gld"
%SYSTEM-E-ENO2, No such file or directory
GTM>WRITE $zgbldir
/usr/dev/mumps.gld
GTM>halt
$
The SET command attempts to change the value of $ZGBLDIR to test.gld.
Because the file does not exist, GT.M reports an error and does not change
the value of $ZGBLDIR.
**Caution**
Attempting to restore an inaccessible initial Global Directory that has
been NEW'd, can cause an error.
Note
Attempting to restore an inaccessible initial Global Directory that has
been NEW'd, can cause an error.
2 $ZINTerrupt
$ZINTerrupt
$ZINT[ERRUPT] specifies the code to be XECUTE'd when an interrupt (for
example, through a MUPIP INTRPT) is processed. While a $ZINTERRUPT action
is in process, any additional interrupt signals are discarded. When an
interrupt handler is invoked, the current values of $REFERENCE is saved
and restored when the interrupt handler returns. The current device ($IO)
is neither saved nor restored.
GT.M permits the SET command to modify the value of $ZINTERRUPT.
If an interrupt handler changes the current IO device (via USE), it is the
responsibility of the interrupt handler to restore the current IO device
before returning. There are sufficient legitimate possibilities why an
interrupt routine would want to change the current IO device (for example;
daily log switching), that this part of the process context is not saved
and restored automatically.
The initial value for $ZINTERRUPT is taken from the UNIX environment
variable gtm_zinterrupt if it is specified, otherwise it defaults to the
following string:
IF $ZJOBEXAM()
The IF statement executes the $ZJOBEXAM function but effectively discards
the return value.
**Note**
If the default value for $ZINTERRUPT is modified, no $ZJOBEXAM() will
occur unless the replacement value directly or indirectly invokes that
function. In other words, while $ZJOBEXAM() is part of the interrupt
handling by default, it is not an implicit part of the interrupt handling.
3 Interrupt_Handling
Interrupt Handling
GT.M process execution is interruptible with the following events:
When GT.M detects any of these events, it transfers control to a vector
that depends on the event. For CTRAP characters and ZMAXTPTIME, GT.M uses
the $ETRAP or $ZTRAP vectors described in more detail in the Error
Processing chapter. For INTRPT and $ZTEXit, it XECUTEs the interrupt
handler code placed in $ZINTERRUPT. If $ZINTERRUPT is an empty string,
nothing is done in response to a MUPIP INTRPT. The default value of
$ZINTERRUPT is "IF $ZJOBEXAM()" which redirects a dump of ZSHOW "*" to a
file and reports each such occasion to the operator log. For CTRL+C with
CENABLE, it enters Direct Mode to give the programmer control.
GT.M recognizes most of these events when they occur but transfers control
to the interrupt vector at the start of each M line, at each iteration of
a FOR LOOP, at certain points during the execution of commands which may
take a "long" time. For example, ZWRITE, HANG, LOCK, MERGE, ZSHOW "V",
OPENs of disk files and FIFOs, OPENs of SOCKETs with the CONNECT parameter
(unless zero timeout,) WRITE /WAIT for SOCKETs, and READ for terminals,
SOCKETs, FIFOs, and PIPEs. If +$ZTEXIT evaluates to a truth value at the
outermost TCOMMIT or TROLLBACK, GT.M XECUTEs $ZINTERRUPT after completing
the commit or rollback. CTRAP characters are recognized when they are
typed on OpenVMS but when they are read on UNIX.
If an interrupt event occurs in a long running external call (for example,
waiting in a message queue), GT.M recognizes the event but makes the
vector transfer after the external call returns when it reaches the next
appropriate execution boundary.
When an interrupt handler is invoked, GT.M saves and restores the current
values of $REFERENCE. However, the current device ($IO) is neither saved
nor restored. If an interrupt handler changes $IO (via USE), ensure that
the interrupt handler restores the current device before returning. To
restore the device which was current when the interrupt handler began,
specify USE without any deviceparameters. Any attempt to do IO on a device
which was actively doing IO when the interrupt was recognized may result
in a ZINTERCURSEIO error.
Example:
set $zinterrupt="do ^interrupthandler($io)"
interrupthandler(currentdev)
do ^handleinterrupt ; handle the interrupt
use currentdev ; restore the device which was current when the interrupt was recognized
quit
The use of the INTRPT facility may create a temporary hang or pause while
the interrupt handler code is executed. For the default case where the
interrupt handler uses IF $ZJOBEXAM() to create a dump, the pause duration
depends on the number of local variables in the process at the time of the
dump and on the speed of the disk being written to. The dumps are slower
on a network-mounted disk than on a disk directly connected to the local
system. Any interrupt driven code should be designed to account for this
issue.
**Important**
Because sending an interrupt signal requires the sender to have
appropriate permissions, the use of the job interrupt facility itself does
not present any inherent security exposures. Nonetheless, because the dump
files created by the default action contain the values of every local
variable in the context at the time they are made, inappropriate access to
the dump files would constitute a security exposure. Make sure the design
and implementation of any interrupt logic includes careful consideration
to security issues.
During the execution of the interrupt handling code, $ZINITERRUPT
evaluates to 1 (TRUE).
If an error occurs while compiling the $ZINTERRUPT code, the error handler
is not invoked (the error handler is invoked if an error occurs while
executing the $ZINTERRUPT code), GT.M sends the GTM-ERRWZINTR message and
the compiler error message to the operator log facility. If the GT.M
process is at a direct mode prompt or is executing a direct mode command
(for example, a FOR loop), GT.M sends also sends the GTM-ERRWZINTR error
message to the user console along with the compilation error. In both
cases, the interrupted process resumes execution without performing any
action specified by the defective $ZINTERRUPT vector.
If GT.M encounters an error during creation of the interrupt handler's
stack frame (before transferring control to the application code specified
by the vector), that error is prefixed with a GTM-ERRWZINTR error. The
error handler then executes normal error processing associated with the
interrupted routine.
**Note**
The interrupt handler does not operate "outside" the current M environment
but rather within the environment of the process.
TP transaction is in progress (0<$TLEVEL), updates to globals are not safe
since a TP restart can be signaled at any time prior to the transaction
being committed - even after the interrupt handler returns. A TP restart
reverses all global updates and unwinds the M stack so it is as if the
interrupt never occurred. The interrupt handler is not redriven as part of
a transaction restart. Referencing (reading) globals inside an interrupt
handler can trigger a TP restart if a transaction is active. When
programming interrupt handling, either discard interrupts when 0<$TLEVEL
(forcing the interrupting party to try again), or use local variables that
are not restored by a TRESTART to defer the interrupt action until after
the final TCOMMIT.
2 $ZINInterrupt
$ZINInterrupt
$ZINI[NTERRUPT] evaluates to 1 (TRUE) when a process is executing code
initiated by the interrupt mechanism, and otherwise 0 (FALSE).
GT.M does not permit the SET or NEW commands to modify $ZININTERRUPT.
2 $ZIO
$ZIO
$ZIO contains the translated name of the current device, in contrast to
$IO, which contains the name as specified by the USE command.
GT.M does not permit the SET or NEW command to modify $ZIO.
An example where $ZIO contains a value different from $IO is if the
environment variable gtm_principal is defined.
Example:
$ gtm_principal="foo"
$ export gtm_principal
GTM>WRITE $IO
foo
GTM>WRITE $ZIO
/dev/pts/8
Notice that $ZIO contains the actual terminal device name while $IO
contains the string pointed to by the environment variable gtm_principal.
2 $ZJob
$ZJob
$ZJ[OB] holds the pid of the process created by the last JOB command
performed by the current process.
GT.M initializes $ZJOB to zero (0) at process startup. If the JOB command
fails to spawn a new job, GT.M sets $ZJOB to zero (0). Note that because
of the left to right evaluation order of M, using $ZJOB in the
jobparameter string results in using the value created by the last, rather
than the current JOB command, which is not likely to match common coding
practice.
GT.M does not permit the SET or NEW command to modify $ZJOB.
2 $ZKey
$ZKey
For Socket devices:
$ZKEY contains a list of sockets in the current SOCKET device which are
ready for use. Its contents include both non selected but ready sockets
from the prior WRITE /WAITs and any sockets with unread data in their GT.M
buffer. $ZKEY can be used any time a SOCKET device is current. Once an
incoming socket (that is, "LISTENING") has been accepted either by being
selected by WRITE /WAIT or by USE socdev:socket="listeningsocket", it is
removed from $ZKEY.
$ZKEY contains any one of the following values:
"LISTENING|<listening_socket_handle>|{<portnumber>|</path/to/LOCAL_socket>}"
"READ|<socket_handle>|<address>"
If $ZKEY contains one or more "READ|<socket_handle>|<address>" entries, it
means there are ready to READ sockets that were selected by WRITE /WAIT or
were partially read and there is data left in their buffer. Each entry is
delimited by a ";".
$ZKEY is empty if no sockets have data in the buffer and there are no
unaccepted incoming sockets from previous WRITE /WAITs.
For Sequential File Device:
$ZKEY contains the current position in the file based on the last READ.
This is in bytes for STREAM and VARIABLE formats, and in a record,byte
pair for FIXED format. For FIXED format, SEEKs and normal READs always
produce a zero byte position; a non-zero byte position in $ZKEY for FIXED
format operation indicates a partially read record, caused by a READ # or
READ *. In FIXED mode, the information returned for $ZKEY is a function of
record size, and, if a USE command changes record size by specifying the
WIDTH deviceparameter while the file is open, $ZKEY offsets change
accordingly; if record size changes, previously saved values of $ZKEY are
likely inappropriate for use with SEEK.
2 $ZLevel
$ZLevel
$ZL[EVEL] contains an integer value indicating the "level of nesting"
caused by DO commands, XECUTE commands, and extrinsic functions in the M
invocation stack.
$ZLEVEL has an initial value of one (1) and increments by one with each
DO, XECUTE or extrinsic function. Any QUIT that does not terminate a FOR
loop decrements $ZLEVEL. ZGOTO may also reduce $ZLEVEL. In accordance with
the M standard, a FOR command does not increase $ZLEVEL. M routines cannot
modify $ZLEVEL with the SET or NEW commands.
Use $ZLEVEL in debugging or in an error-handling mechanism to capture a
level for later use in a ZGOTO argument.
Example:
GTM>zprint ^zleve
zleve;
do B
write X,!
quit
B
goto C
quit
C
do D
quit
D
set X=$ZLEVEL
quit
GTM>do ^zleve
4
GTM>
This program, executed from Direct Mode, produces a value of 4 for
$ZLEVEL. If you run this program from the shell, the value of $ZLEVEL is
three (3).
2 $ZMAXTPTIme
$ZMAXTPTIme
$ZMAXTPTI[ME] contains an integer value indicating the time duration GT.M
should wait for the completion of all activities fenced by the current
transaction's outermost TSTART/TCOMMIT pair.
$ZMAXTPTIME can be SET but cannot be NEWed.
$ZMAXTPTIME takes its value from the environment variable gtm_zmaxtptime.
If gtm_zmaxtptime is not defined, the initial value of $ZMAXTPTIME is zero
(0) seconds which indicates "no timeout" (unlimited time). The value of
$ZMAXTPTIME when a transaction's outermost TSTART operation executes
determines the timeout setting for that transaction.
When a $ZMAXTPTIME expires, GT.M executes the $ETRAP/$ZTRAP exception
handler currently in effect.
**Note**
Negative values of $ZMAXTPTIME are also treated as "no timeout". Timeouts
apply only to the outermost transaction, that is, $ZMAXTPTIME has no
effect when TSTART is nested within another transaction.
Example:
Test;testing TP timeouts
set $ZMAXTPTIME=6,^X=0,^Y=0,^Z=0
write "Start with $ZMAXTPTIME=",$ZMAXTPTIME,":",!
for sleep=3:2:9 do
. set retlvl=$zl
. do longtran;ztrap on longtran
;continues execution
;on next line
. write "(^X,^Y)=(",^X,",",^Y,")",!
write !,"Done TP Timeout test.",!
quit
longtran ;I/O in TP doesn't get rolled back
set newzt="set $ZT="""" ";avoid recursive ZTRAP
set $ZT=newzt_" goto err"
tstart ():serial ;plain tstart works as well
set ^X=1+^X
write !,"^X=",^X,",will set ^Y to ",sleep
write " in ",sleep," seconds..."
hang sleep
set ^Y=sleep
write "^Y=",^Y
tcommit
write "...committed.",!
quit
err;
set $ZT=""
write !,"In $ZTRAP handler. Error was: "
write !," ",$zstatus
if $TLEVEL do ;test allows handler use outside of TP
. trollback
. write "Rolled back transaction."
write !
zgoto retlvl
Results:
Start with $ZMAXTPTIME=6:
^X=1,will set ^Y to 3 in 3 seconds...^Y=3...committed.
^X=2,will set ^Y to 5 in 5 seconds...^Y=5...committed.
^X=3,will set ^Y to 7 in 7 seconds...
In $ZTRAP handler. Error was:
150377322,longtran+7^tptime,%GTM-E-TPTIMEOUT, Transaction timeoutRolled back transaction.
^X=3,will set ^Y to 9 in 9 seconds...
In $ZTRAP handler. Error was:
150377322,longtran+7^tptime,%GTM-E-TPTIMEOUT, Transaction timeoutRolled back transaction.
Done TP Timeout test.
2 $ZMOde
$ZMOde
$ZMO[DE] contains a string value indicating the process execution mode.
The mode can be:
* INTERACTIVE
* OTHER
M routines cannot modify $ZMODE.
Example:
GTM>WRITE $ZMODE
INTERACTIVE
This displays the process mode.
2 $ZONLNrlbk
$ZONLNrlbk
$ZONLNRLBK increments every time a process detects a concurrent MUPIP
JOURNAL -ONLINE -ROLLBACK.
GT.M initializes $ZONLNRLBK to zero (0) at process startup. GT.M does not
permit the SET or NEW commands to modify $ZONLNRLBK.
2 $ZPATNumeric
$ZPATNumeric
$ZPATN[UMERIC] is a read-only intrinsic special variable that determines
how GT.M interprets the patcode "N" used in the pattern match operator.
With $ZPATNUMERIC="UTF-8", the patcode "N" matches any numeric character
as defined by UTF-8 encoding. With $ZPATNUMERIC="M", GT.M restricts the
patcode "N" to match only ASCII digits 0-9 (that is, ASCII 48-57). When a
process starts in UTF-8 mode, intrinsic special variable $ZPATNUMERIC
takes its value from the environment variable gtm_patnumeric. GT.M
initializes the intrinsic special variable $ZPATNUMERIC to "UTF-8" if the
environment variable gtm_patnumeric is defined to "UTF-8". If the
environment variable gtm_patnumeric is not defined or set to a value other
than "UTF-8", GT.M initializes $ZPATNUMERIC to "M".
GT.M populates $ZPATNUMERIC at process initialization from the environment
variable gtm_patnumeric and does not allow the process to change the
value.
For characters in Unicode, GT.M assigns patcodes based on the default
classification of the Unicode character set by the ICU library with three
adjustments:
1. If $ZPATNUMERIC is not "UTF-8", non-ASCII decimal digits are
classified as A.
2. Non-decimal numerics (Nl and No) are classified as A.
3. The remaining characters (those not classified by ICU functions:
u_isalpha, u_isdigit, u_ispunct, u_iscntrl, 1), or 2) above) are
classified into either patcode P or C. The ICU function u_isprint is
used since is returns "TRUE" for non-control characters.
The following table contains the resulting Unicode general category to M
patcode mapping:
+------------------------------------------------------------------------+
| Unicode General Category | GT.M patcode Class |
|------------------------------+-----------------------------------------|
| L* (all letters) | A |
|------------------------------+-----------------------------------------|
| M* (all marks) | P |
|------------------------------+-----------------------------------------|
| Nd (decimal numbers) | N (if decimal digit is ASCII or |
| | $ZPATNUMERIC is "UTF-8", otherwise A |
|------------------------------+-----------------------------------------|
| Nl (letter numbers) | A (examples of Nl are Roman numerals) |
|------------------------------+-----------------------------------------|
| No (other numbers) | A (examples of No are fractions) |
|------------------------------+-----------------------------------------|
| P* (all punctuation) | P |
|------------------------------+-----------------------------------------|
| S* (all symbols) | P |
|------------------------------+-----------------------------------------|
| Zs (spaces) | P |
|------------------------------+-----------------------------------------|
| Zl (line separators) | C |
|------------------------------+-----------------------------------------|
| Zp (paragraph separators) | C |
|------------------------------+-----------------------------------------|
| C* (all control code points) | C |
+------------------------------------------------------------------------+
For a description of the Unicode general categories, refer to
http://unicode.org/charts/.
Example:
GTM>write $zpatnumeric
UTF-8
GTM>Write $Char($$FUNC^%HD("D67"))?.N ; This is the Malayalam decimal digit 1
1
GTM>Write 1+$Char($$FUNC^%HD("D67"))
1
GTM>Write 1+$Char($$FUNC^%HD("31")) ; This is the ASCII digit 1
2
2 $ZPOSition
$ZPOSition
$ZPOS[ITION] contains a string value specifying the current entryref,
where entryref is [label][+offset]^routine, and the offset is evaluated
from the closest preceding label.
GT.M does not permit the SET or NEW commands to modify $ZPOSITION.
Example:
GTM>WRITE !,$ZPOS,! ZPRINT @$ZPOS
This example displays the current location followed by the source code for
that line.
2 $ZPROMpt
$ZPROMpt
$ZPROM[PT] contains a string value specifying the current Direct Mode
prompt. By default, GTM>is the Direct Mode prompt. M routines can modify
$ZPROMPT by means of a SET command. $ZPROMPT cannot exceed 16 characters.
If an attempt is made to assign $ZPROMPT to a longer string, only the
first 16 characters will be taken.
In UTF-8 mode, if the 31st byte is not the end of a valid UTF-8 character,
GT.M truncates the $ZPROMPT value at the end of last character that
completely fits within the 31 byte limit.
The environment gtm_prompt initializes $ZPROMPT at process startup.
Example:
GTM>set $zprompt="Test01">"
Test01>set $zprompt="GTM>"
This example changes the GT.M prompt to Test01> and then back to GTM>.
2 $ZREalstor
$ZREalstor
$ZREALSTOR contains the total memory (in bytes) allocated by the GT.M
process, which may or may not actually be in use. It provides one view
(see also $ZALLOCSTOR and ZUSEDSTOR) of the process memory utilization and
can help identify storage related problems. GT.M does not permit
$ZREALSTOR to be SET or NEWed.
2 $ZROutines
$ZROutines
$ZRO[UTINES] contains a string value specifying a directory or list of
directories containing object files. Each object directory may also have
an associated directory, or list of directories, containing the
corresponding source files. These directory lists are used by certain GT.M
functions, primarily auto-ZLINK, to locate object and source files. The
order in which directories appear in a given list determines the order in
which they are searched for the appropriate item.
Searches that use $ZROUTINES treat files as either object or source files.
GT.M treats files with an extension of .o as object files and files with
an extension of .m as source files.
**Note**
Paths used in $ZROUTINES to locate routines must not include embedded
spaces, as $ZROUTINES uses spaces as delimiters.
3 Establishing_the_Value_from_$gtmroutines
Establishing the Value from $gtmroutines
When the environment variable gtmroutines is defined, GT.M initializes
$ZROUTINES to the value of gtmroutines. Otherwise, GT.M initializes
$ZROUTINES to a null value. When $ZROUTINES is null, GT.M attempts to
locate all source and object files in the current working directory.
$ZROUTINES="" is equivalent to $ZROUTINES=".".
Commands or functions such as DO, GOTO, ZGOTO, ZBREAK, ZPRINT, and $TEXT
may auto-ZLINK and thereby indirectly use $ZROUTINES. If their argument
does not specify a directory, ZEDIT and explicit ZLINK use $ZROUTINES.
ZPRINT and $TEXT use $ZROUTINES to locate a source file if GT.M cannot
find the source file pointed to by the object file.
3 Setting_a_Value_for_$ZROutines
Setting a Value for $ZROutines
$ZRO[UTINES] is a read-write Intrinsic Special Variable, so M can also SET
the value.
By default, each directory entry in $ZROUTINES is assumed to contain both
object and source files. However, each object directory may have an
associated directory or list of directories to search for the
corresponding source files. This is done by specifying the source
directory list, in parentheses, following the object directory
specification.
If the command specifies more than one source directory for an object
directory, the source directories must be separated by spaces, and the
entire list must be enclosed in parentheses ( ) following the object
directory-specification. If the object directory should also be searched
for source, the name of that directory must be included in the
parentheses, (usually as the first element in the list).
Directory-specifications may also include empty parentheses, directing
GT.M to proceed as if no source files exist for objects located in the
qualified directory.
To set $ZROUTINES outside of M, use the appropriate shell command to set
gtmroutines. Because gtmroutines is a list, enclose the value in quotation
marks (" ").
Changes to the value of $ZROUTINES during a GT.M invocation only last for
the current invocation, and do not change the value of gtmroutines.
Directory specifications may include an environment variable. When GT.M
SETs $ZROUTINES, it translates all environment variables and verifies the
syntax and the existence of all specified directories. If $ZROUTINES is
set to an invalid value, GT.M generates a run-time error and does not
change the value of $ZROUTINES. Because the environment variables are
translated when $ZROUTINES is set, any changes to their definition have no
effect until $ZROUTINES is set again.
3 $ZROutines_Examples
$ZROutines Examples
Example:
GTM>s $zroutines=".(../src) $gtm_dist"
This example directs GTM to look for object modules first in your current
directory, then in the distribution directory that contains the percent
routines. GT.M locates sources for objects in your current directory in
the sibling /src directory.
Example:
$ gtmroutines="/usr/jones /usr/smith"
$ export gtmroutines
$ gtm
GTM>write $zroutines
"/usr/jones /usr/smith"
GTM>set $zro="/usr/jones/utl /usr/smith/utl"
GTM>write $zroutines
"/usr/jones/utl /usr/smith/utl"
GTM>halt
$ echo $gtmroutines
/usr/jones /usr/smith
This example defines the environment variable gtmroutines. Upon entering
GT.M Direct Mode $zroutines has the value supplied by gtmroutines. The SET
command changes the value. When the GT.M image terminates, the shell echo
command demonstrates that gtmroutines has not been modified by the M SET
command.
Example:
GTM>SET $ZRO=". /usr/smith"
This example sets $zroutines to a list containing two directories.
Example:
GTM>set $zro="/usr/smith(/usr/smith/tax /usr/smith/fica)"
This example specifies that GT.M should search the directory /usr/smith
for object files, and the directories /usr/smith/tax and /usr/smith/fica
for source files. Note that in this example. GT.M does not search
/usr/smith for source files.
Example:
GTM>set $zro="/usr/smith(/usr/smith /usr/smith/tax /usr/smith/fica)"
This example specifies that GT.M should search the directory /usr/smith
for object files and the directories /usr/smith/tax and /usr/smith/fica
for source files. Note that the difference between this example and the
previous one is that GT.M searches /usr/smith for both object and source
files.
Example:
GTM>set $zro="/usr/smith /usr/smith/tax() /usr/smith/fica"
This specifies that GT.M should search /usr/smith and /usr/smith/fica for
object and source files. However, because the empty parentheses indicate
directories searched only for object files, GT.M does not search
/usr/smith/tax for source files.
Omitting the parentheses indicates that GT.M can search the directory for
both source and object files. $ZROUTINES=/usr/smith is equivalent to
$ZROUTINES=/usr/smith(/usr/smith).
3 $ZROutines_Search_Types
$ZROutines Search Types
GT.M uses $ZRO[UTINES] to perform three types of searches:
* Object-only when the command or function using $ZROUTINES requires a
.o file extension.
* Source-only when the command or function using $ZROUTINES requires a
file extension other than .o.
* Object-source match when the command or function using $ZROUTINES does
not specify a file extension.
An explicit ZLINK that specifies a non .OBJ .o extension is considered as
a function that has not specified a file extension for the above searching
purposes.
All searches proceed from left to right through $ZROUTINES. By default,
GT.M searches directories for both source and object files. GT.M searches
directories followed by empty parentheses ( ) for object files only. GT.M
searches directories in parentheses only for source files.
Once an object-matching search locates an object file, the source search
becomes limited. If the directory containing the object file has an
attached parenthetical list of directories, GT.M only searches the
directories in the attached list for matching source files. If the
directory containing the object files does not have following parentheses,
GT.M restricts the search for matching source files to the same directory.
If the object module is in a directory qualified by empty parentheses,
GT.M cannot perform any operation that refers to the source file.
The following table shows GT.M commands and functions using $ZROUTINES and
the search types they support.
+------------------------------------------------------+
| GT.M Commands and $ZROUTINES Search Types |
|------------------------------------------------------|
| SEARCH/ | FILE | |
| FUNCTION | EXTENSION | SEARCH TYPE |
| | SPECIFIED | |
|------------+-----------+-----------------------------|
| | | OBJ-ONLY | SRC-ONLY | MATCH |
|------------+-----------+----------+----------+-------|
| EXPLICIT | | | | |
| | .o | X | | |
| ZLINK | | | | |
|------------+-----------+----------+----------+-------|
| | Not .o | | | X |
|------------+-----------+----------+----------+-------|
| | None | | | X |
|------------+-----------+----------+----------+-------|
| AUTO-ZLINK | None | | | X |
|------------+-----------+----------+----------+-------|
| ZEDIT | Not .o | | X | |
|------------+-----------+----------+----------+-------|
| ZPRINT | None | | X | |
|------------+-----------+----------+----------+-------|
| $TEXT | None | | X | |
+------------------------------------------------------+
If ZPRINT or $TEXT() require a source module for a routine that is not in
the current image, GT.M first performs an auto-ZLINK with a matching
search.
ZPRINT or $TEXT locate the source module using a file specification for
the source file located in the object module. If GT.M finds the source
module in the directory where it was when it was compiled, the run-time
system does not use $ZROUTINES. If GT.M cannot find the source file in the
indicated location, the run-time system uses $ZROUTINES.
3 $ZROutines_Search_Examples
$ZROutines Search Examples
This section describes a model for understanding $ZROUTINES operations and
the illustrating examples, which may assist you if you wish to examine the
topic closely.
You may think of $ZROUTINES as supplying a two dimensional matrix of
places to look for files. The matrix has one or more rows. The first row
in the matrix contains places to look for object and the second and
following rows contain places to look for source. Each column represents
the set of places that contain information related to the object modules
in the first row of the column.
Example:
GTM>s $zro=". /usr/smi/utl() /usr/jon/utl
(/usr/jon/utl/so /usr/smi/utl)"
The following table illustrates the matrix view of this $ZROUTINES.
+--------------------------------------------------------+
| $ZROUTINES Search Matrix |
|--------------------------------------------------------|
| SEARCH FOR | Column 1 | Column 2 | Column 3 |
|------------+----------+--------------+-----------------|
| OBJECTS | . | /usr/smi/utl | /usr/jon/utl |
|------------+----------+--------------+-----------------|
| SOURCE | . | | /usr/jon/utl/so |
|------------+----------+--------------+-----------------|
| | | | /usr/smi/utl |
+--------------------------------------------------------+
To perform object-only searches, GT.M searches only the directories or
object libraries in the top 'objects' row for each column starting at
column one. If GT.M does not locate the object file in a directory or
object library in the 'objects' row of a column, GT.M begins searching
again in the next column. If GT.M cannot locate the file in any of the
columns, it issues a run-time error.
As illustrated in the preceding table, GT.M searches for object files in
the directories . ,/usr/smi/utl and /usr/jon/utl.
To perform source-only searches, GT.M looks down to the 'source' row at
the bottom of each column, excluding columns headed by object-only
directories (that is, those object directories, which consist of an empty
list of source directories) or object libraries. If GT.M cannot locate the
source file in the 'source' row of a column, it searches the next eligible
column.
To perform object-source match searches, GT.M looks at each column
starting at column one. GT.M does an object-only search in the 'objects'
row of a column and a source-only search in the 'source' row(s) of a
column. If GT.M locates either the object-file or the souce-file, the
search is completed. Else, GT.M starts searching the next column. If GT.M
cannot locate either the object file or the source file in any of the
columns, it issues a run-time error.
As illustrated in the preceding table, GT.M searches for source-files in
the directory "." in column one. If GT.M cannot locate the source file in
".", it omits column two because it is an object-only directory and
instead searches column three. Since column three specifies
/usr/jon/utl/so and /usr/smi/utl, GT.M searches for the source-file in
these directories in column three and not in /usr/jon/utl. If GT.M cannot
locate the source-file in column three, it terminates the search and
issues a run-time error.
Once the object-source match search is done, GT.M now has either the
object-file or source-file or both available. GT.M then recompiles the
source-file based on certain conditions, before linking the object-file
into the current image.
If auto-ZLINK or ZLINK determines that the source file requires
[re]compilation, GT.M places the object file in the above object directory
in the same column as the source file. For example, if GT.M locates the
source file in /usr/smi/utl in column three, GT.M places the resultant
object file in /usr/jon/utl.
3 Shared_Library_File_Specification_in_$ZROUTINES
Shared Library File Specification in $ZROUTINES
The $ZROUTINES ISV allows individual UNIX shared library file names to be
specified in the search path. During a search for auto-ZLINK, when a
shared library is encountered, it is probed for a given routine and, if
found, that routine is linked/loaded into the image. During an explicit
ZLINK, all shared libraries in $ZROUTINES are ignored and are not searched
for a given routine.
$ZROUTINES syntax contains a file-specification indicating shared library
file path. GT.M does not require any designated extension for the shared
library component of $ZROUTINES. Any file specification that does not name
a directory is treated as shared library. However, it is recommended that
the extension commonly used on a given platform for shared library files
be given to any GT.M shared libraries. A shared library component cannot
specify source directories. GT.M reports an error at an attempt to
associate any source directory with a shared library in $ZROUTINES.
The following traits of $ZROUTINES help support shared libraries:
* The $ZROUTINES search continues to find objects in the first place,
processing from left to right, that holds a copy; it ignores any
copies in subsequent locations. However, now for auto-ZLINK, shared
libraries are accepted as object repositories with the same ability to
supply objects as directories.
* Explicit ZLINK, never searches Shared Libraries. This is because
explicit ZLINK is used to link a newly created routine or re-link a
modified routine and there is no mechanism to load new objects into an
active shared library.
* ZPRINT and $TEXT() of the routines in a shared library, read source
file path from the header of the loaded routine. If the image does not
contain the routine, an auto-ZLINK is initiated. If the source file
path recorded in the routine header when the module was compiled
cannot be located, ZPRINT and $TEXT() initiate a search from the
beginning of $ZROUTINES, skipping over the shared library file
specifications. If the located source does not match the code in image
(checked via checksum), ZPRINT generates an object-source mismatch
status and $TEXT() returns a null string.
* ZEDIT, when searching $ZROUTINES, skips shared libraries like explicit
ZLINK for the same reasons. $ZSOURCE ISV is implicitly set to the
appropriate source file.
For example, if libshare.so is built with foo.o compiled from
./shrsrc/foo.m, the following commands specify that GT.M should search the
library ./libshare.so for symbol foo when do ^foo is encountered.
GTM>SET $ZROUTINES="./libshare.so ./obj(./shrsrc)"
GTM>DO ^foo;auto-ZLINK foo - shared
GTM>ZEDIT "foo";edit ./shrsrc/foo.m
GTM>W $ZSOURCE,!;prints foo
GTM>ZPRINT +0^foo;issues a source-object mismatch status TXTSRCMAT error message
GTM>ZLINK "foo";re-compile ./shrsrc/foo.m to generate ./obj/foo.o.
GTM>W $TEXT(+0^foo);prints foo
Note that ZPRINT reports an error, as foo.m does not match the routine
already linked into image. Also note that, to recompile and re-link the
ZEDITed foo.m, its source directory needs to be attached to the object
directory [./obj] in $ZROUTINES. The example assumes the shared library
(libshare.so) has been built using shell commands.
2 $ZSOurce
$ZSOurce
$ZSO[URCE] contains a string value specifying the default pathname for the
ZEDIT and ZLINK commands. ZEDIT or ZLINK without an argument is equivalent
to ZEDIT/ZLINK $ZSOURCE.
$ZSOURCE initially contains the null string. When ZEDIT and ZLINK commands
have a pathname for an argument, they implicitly set $ZSOURCE to that
argument. This ZEDIT/ZLINK argument can include a full pathname or a
relative one. A relative path could include a file in the current
directory, or the path to the file from the current working directory. In
the latter instance, do not include the slash before the first directory
name. $ZSOURCE will prefix the path to the current working directory
including that slash.
The file name may contain a file extension. If the extension is .m or .o,
$ZSOURCE drops it. The ZEDIT command accepts arguments with extensions
other than .m or .o. $ZSOURCE retains the extension when such arguments
are passed.
If $ZSOURCE contains a file with an extension other than .m or .o, ZEDIT
processes it but ZLINK returns an error message
$ZSOURCE is a read-write Intrinsic Special Variable, (i.e., it can appear
on the left side of the equal sign (=) in the argument to the SET
command). A $ZSOURCE value may include an environment variable. GT.M
handles logical names that translate to other logical names by performing
iterative translations according to VMS conventions. If a logical name
translates to a VMS search list, GT.M uses only the first name in the
list.
Example:
GTM>ZEDIT "subr.m"
.
.
GTM>WRITE $ZSOURCE
subr
Example:
GTM>ZEDIT "test"
.
.
.
GTM>WRITE $ZSOURCE
"test"
Example:
GTM>ZEDIT "/usr/smith/report.txt"
.
.
.
GTM>WRITE $ZSOURCE
/usr/smith/report.txt
Example:
GTM>ZLINK "BASE.O"
.
.
.
GTM>WRITE $ZSOURCE
BASE
2 $ZStatus
$ZStatus
$ZS[TATUS] contains a string value specifying the error condition code and
location of the last exception condition that occurred during routine
execution.
GT.M maintains $ZSTATUS as a string consisting of three or more
substrings. The string consists of the following:
Format: %<FAC>-<SEV>-<ID>, <TEXT>
Example: %GTM-E-DIVZERO, Attempt to divide by zero
GT.M sets $ZSTATUS when it encounters errors during program execution, but
not when it encounters errors in a Direct Mode command.
$ZSTATUS is a read-write Intrinsic Special Variable, (i.e., it can occur
on the left side of the equal sign (=) in the argument to the SET
command). While it will accept any string, FIS recommends setting it to
null. M routines cannot modify $ZSTATUS with the NEW command.
Example:
GTM>WRITE $ZSTATUS
150373110,+1^MYFILE,%GTM-E-DIVZERO,
Attempt to divide by zero
This example displays the status generated by a divide by zero (0).
2 $ZSTep
$ZSTep
$ZST[EP] contains a string value specifying the default action for the
ZSTEP command. $ZSTEP provides the ZSTEP action only when the ZSTEP
command does not specify an action.
$ZSTEP initially contains the string "B" to enter direct mode. $ZSTEP is a
read-write Intrinsic Special Variable, (i.e., it can appear on the left
side of the equal sign (=) in the argument to the SET command).
Example:
GTM>WRITE $ZSTEP
B
GTM>
This example displays the current value of $ZSTEP, which is the default.
Example:
GTM>SET $ZSTEP="ZP @$ZPOS B"
This example sets $ZSTEP to code that displays the contents of the next
line to execute, and then enters Direct Mode.
2 $ZSYstem
$ZSYstem
$ZSY[STEM] holds the value of the status code for the last subprocess
invoked with the ZSYSTEM command.
2 $ZTExit
$ZTExit
$ZTE[XIT] contains a string value that controls the GT.M interrupt
facility at the transaction commit or rollback. At each outermost TCOMMIT
or TROLLBACK, If +$ZTEXIT evaluates to non-zero (TRUE), then $ZINTERRUPT
is XECUTEd after completing the commit or rollback.
$ZTEXIT is a read-write ISV, that is, it can appear on the left side of
the equal sign (=) in the argument to the SET command. M routines cannot
NEW $ZTEXIT. GT.M initializes $ZTEXIT to null at the process startup. Note
that the changes to the value of $ZTEXIT during a GT.M invocation last for
the entire duration of the process, so it is the application's
responsibility to reset $ZTEXIT after $ZINTERRUPT is delivered in order to
turn off redelivering the interrupt every subsequent transaction commit or
rollback.
Example:
$ export sigusrval=10
$ /usr/lib/fis-gtm/V6.1-000_x86_64/gtm
GTM>zprint ^ztran
foo;
set $ztexit=1
set $zinterrupt="d ^throwint"
tstart ()
for i=1:1:10 do
. set ^ACN(i,"bal")=i*100
tstart ()
do ^throwint
;do ^proc
tcommit:$tlevel=2
for i=1:1:10 do
. set ^ACN(i,"int")=i*0.05
;do ^srv
if $tlevel trollback
;do ^exc
set $ztexit="",$zinterrupt=""
quit
bar;
write "Begin Transaction",!
set $ztexit=1
tstart ()
i '$zsigproc($j,$ztrnlnm("sigusrval")) write "interrupt sent...",!!
for i=1:1:4 set ^B(i)=i*i
tcommit
write "End Transaction",!
;do ^srv
quit
GTM>zprint ^throwint
throwint
set $zinterrupt="write !,""interrupt occurred at : "",$stack($stack-1,""PLACE""),! set $ztexit=1"
if '$zsigproc($job,$ztrnlnm("sigusrval")) write "interrupt sent to process"
write "***************************************",!!
quit
GTM>do foo^ztran
interrupt sent to process
interrupt occurred at : throwint+3^throwint
***************************************
interrupt occurred at : foo+13^ztran
GTM>
In the above call to foo^ztran, the interrupt handler is a user-defined
routine, throwint. The process is sent a signal (SIGUSR1), and $ZINTERRUPT
is executed. At the outermost trollback, the interrupt is rethrown,
causing $ZINTERRUPT to be executed again.
Example:
GTM>w $zinterrupt
"IF $ZJOBEXAM()"
GTM>zsystem "ls GTM*"
ls: No match.
GTM>do bar^ztran
Begin Transaction
interrupt sent...
End Transaction
GTM>zsystem "ls GTM*"
GTM_JOBEXAM.ZSHOW_DMP_3951_1 GTM_JOBEXAM.ZSHOW_DMP_3951_2
GTM>
This uses the default value of $ZINTERRUPT to service interrupts issued to
the process. The $ZJOBEXAM function executes a ZSHOW "*", and stores the
output in each GTM_ZJOBEXAM_ZSHOW_DMP for the initial interrupt, and at
tcommit when the interrupt is rethrown.
2 $ZTrap
$ZTrap
$ZT[RAP] contains a string value that GT.M XECUTEs when an error occurs
during routine execution.
**Note**
The following discussion assumes that $ETRAP error handling is
simultaneously not in effect (that is, $ETRAP="").
When the $ZTRAP variable is not null, GT.M executes $ZTRAP at the current
level. The $ZTRAP variable has the initial value of "B," and puts the
process in Direct Mode when an error condition occurs. If the value of
$ZTRAP is null (""), an exception causes the image to run-down with the
condition code associated with the exception. If $ZTRAP contains invalid
source code, GT.M displays an error message and puts the process into
Direct Mode.
$ZTRAP is a read-write Intrinsic Special Variable, (that is, it can appear
on the left side of the equal sign (=) in the argument to the SET
command).
$ZTRAP may also appear as an argument to an inclusive NEW command. NEW
$ZTRAP causes GT.M to set $ETRAP or $ZTRAP, whichever is active, to null
($ETRAP="" or $ZTRAP="") and stack its old value. The NEW command puts the
target ISV in control for error handling. When the program QUITs from the
invocation level where the NEW occurred, GT.M restores the value
previously stacked by the NEW. NEW $ZTRAP provides nesting of $ZTRAP.
Because $ZTRAP="" terminates the image when an error occurs, SET $ZTRAP=
generally follows immediately after NEW $ZTRAP. You may use this technique
to construct error handling strategies corresponding to the nesting of
your programs. If the environment variable gtm_ztrap_new evaluates to
boolean TRUE (case insensitive string "TRUE", or case insensitive string
"YES", or a non-zero number), $ZTRAP is NEWed when $ZTRAP is SET;
otherwise $ZTRAP is not stacked when it is SET.
**Note**
QUIT from a $ZTRAP terminates the level at which the $ZTRAP was activated.
Keep $ZTRAP simple and put complicated logic in another routine. If the
action specified by $ZTRAP results in another run-time error before
changing the value of $ZTRAP, GT.M invokes $ZTRAP until it exhausts the
process stack space, terminating the image. Carefully debug exception
handling. For more information on error handling, refer "Error
Processing".
Example:
GTM>S $ZTRAP="ZP @$ZPOS B"
This example modifies $ZTRAP to display source code for the line where
GT.M encounters an error before entering Direct Mode.
There are four settings of $ZTRAP controlled by the UNIX environment
variable gtm_ztrap_form.
The four settings of gtm_ztrap_form are:
* code - If gtm_ztrap_form evaluates to "code" (or a value that is not
one of the subsequently described values), then GT.M treats $ZTRAP as
code and handles it as previously described in the documentation.
* entryref - If gtm_ztrap_form evaluates to "entryref" then GT.M treats
it as an entryref argument to an implicit GOTO command.
* adaptive - If gtm_ztrap_form evaluates to "adaptive" then if $ZTRAP
does not compile to valid M code, then $ZTRAP is treated as just
described for "entryref." Since there is little ambiguity, code and
entryref forms of $ZTRAP can be intermixed in the same application.
**Important**
GT.M attempts to compile $ZTRAP before evaluating $ZTRAP as an
entryref. Because GT.M allows commands without arguments such as QUIT,
ZGOTO, or HANG as valid labels, be careful not to use such keywords as
labels for error handling code in "adaptive" mode.
* pope[ntryref] / popa[daptive] - If gtm_ztrap_form evaluates to
"POPE[NTRYREF]" or "POPA[DAPTIVE]" (case insensitive) and $ZTRAP value
is in the form of entryref, GT.M unwinds the M stack from the level at
which an error occurred to (but not including) the level at which
$ZTRAP was last SET. Then, GT.M transfers control to the entryref in
$ZTRAP at the level where the $ZTRAP value was SET. If the UNIX
environment variable gtm_zyerror is defined to a valid entryref, GT.M
transfers control to the entryref specified by GTM_ZYERROR (with an
implicit DO) after unwinding the stack and before transferring control
to the entyref specified in $ZTRAP.
**Note**
Like $ZTRAP values, invocation of device EXCEPTION values follow the
pattern specified by the current gtm_ztrap_form setting.
2 $ZUSedstor
$ZUSedstor
$ZUSEDSTOR is the value in $ZALLOCSTOR minus storage management overhead
and represents the actual memory, in bytes, requested by current
activities. It provides one view (see also $ZALLOCSTOR and $ZREALSTOR) of
the process memory utilization and can help identify storage related
problems. GT.M does not permit $ZUSEDSTOR to be SET or NEWed.
2 $ZVersion
$ZVersion
$ZV[ERSION] contains a string value specifying the currently installed
GT.M. $ZV[ERSION] is a space-delimited string with four pieces as follows:
<product> <release> <OS> <architecture>
o <product> is always "GT.M".
o <release> always begins with "V", and has the structure
V<DB_Format>.<major_release>-<minor_release>[<bug_fix_level>] where:
o <DB_Format> identifies the block format of GT.M database files
compatible with the release. For example, V4, V5, and V6. The
<DB_Format> piece in $ZVERSION does not change even when a MUPIP
UPRGRADE or MUPIP DOWNGRADE changes the DB Format element in the
database fileheader.
o <major_release> identifies a release with major enhancements.
o <minor_release> identifies minor enhancements to a major release.
The classification of major and minor enhancements is at the
discretion of FIS.
o An optional <bug_fix_level> is an upper-case letter indicating
bug fixes but no new enhancements. Note that GT.M is built
monolithically and never patched. Even though a bug fix release
has only bug fixes, it should be treated as a new GT.M release
and installed in a separate directory.
o <OS> is the host operating system name.
o <architecture> is the hardware architecture for which the release of
GT.M is compiled. Note that GT.M retains it original names for
continuity even if vendor branding changes, for example, "RS6000".
M routines cannot modify $ZVERSION.
Example:
GTM>w $zversion
GT.M V6.0-003 Linux x86_64
This example displays the current version identifier for GT.M.
2 $ZYERror
$ZYERror
$ZYER[ROR] is a read/write ISV that contains a string value pointing to an
entryref. After GT.M encounters an error, if $ZYERROR is set a non-null
value, GT.M invokes the routine at the entryref specified by $ZYERROR with
an implicit DO. It is intended that the code invoked by $ZYERROR use the
value of $ZSTATUS to select or construct a value to which it SETs $ZERROR.
If $ZYERROR is not a valid entryref or if an error occurs while executing
the entryref specified by $ZYERROR, GT.M SETs $ZERROR to the error status
encountered. GT.M then returns control to the M code specified by
$ETRAP/$ZTRAP or device EXCEPTION.
$ZYERROR is implicitly NEWed on entry to the routine specified by
$ZYERROR. However, if GT.M fails to compile, GT.M does not transfer
control to the entryref specified by $ZYERROR.
GT.M permits $ZYERROR to be modified by the SET and NEW commands.
2 Triggers_ISVs
Triggers ISVs
GT.M provides nine ISVs (Intrinsic Special Variables) to facilitate
trigger operations. With the exception of $ZTWORMHOLE, all numeric
trigger-related ISVs return zero (0) outside of a trigger context;
non-numeric ISVs return the empty string.
3 $ZTDAta
$ZTDAta
Within trigger context, $ZTDATA returns $DATA(@$REFERENCE)#2 for a SET or
$DATA(@$REFERENCE) for a KILL, ZKILL or ZWITHDRAW prior to the explicit
update. This provides a fast path alternative, avoiding the need for
indirection in trigger code, to help trigger code determine the
characteristics of the triggering node prior to the triggering update. For
a SET, it shows whether the node did or did not hold data - whether a SET
is modifying the contents of an existing node or creating data at a new
node. For a KILL it shows whether the node had descendants and whether it
had data.
3 $ZTLevel
$ZTLevel
Within trigger context, $ZTLEVEL returns the current level of trigger
nesting (invocation by a trigger of an additional trigger by an update in
trigger context).
$ZTLEVEL greater than one (>1) indicates that there are nested triggers in
progress. When a single update invokes multiple triggers solely because of
multiple trigger matches of that initial (non-trigger) update, they are
not nested (they are chained) and thus all have same $ZTLEVEL.
Example:
+^Cycle(1) -commands=Set -xecute="Write ""$ZTLevel for ^Cycle(1) is: "",$ZTLevel Set ^Cycle(2)=1"
+^Cycle(2) -commands=Set -xecute="Write ""$ZTLevel for ^Cycle(2) is: "",$ZTLevel Set ^Cycle(1)=1"
These trigger definitions show different values of $ZTLEVEL when two
triggers are called recursively (and pathologically).
+^Acct("ID") -commands=set -xecute="set ^Acct(1)=$ztvalue+1"
+^Acct(sub=:) -command=set -xecute="set ^X($ztvalue)=sub"
SET ^Acct("ID")=10 invokes both the above triggers in some order and
$ZTLEVEL will have the same value in both because these triggers are
chained rather than nested.
3 $ZTNAME
$ZTNAME
Within a trigger context, $ZTNAME returns the trigger name. Outside a
trigger context, $ZTNAME returns an empty string.
3 $ZTOLdval
$ZTOLdval
Within trigger context, $ZTOLDVAL returns the prior (old) value of the
global node whose update caused the trigger invocation. This provides a
fast path alternative to $GET(@$REFERENCE) at trigger entry (which avoids
the heavyweight indirection ). If there are multiple triggers matching the
same node (chained), $ZTOLDVAL returns the same result for each of them.
Example:
+^Acct(1,"ID") -commands=Set -xecute="Write:$ZTOLdval ""The prior value of ^Acct(1,ID) was: "",$ZTOLdval"
This trigger gets invoked with a SET and displays the prior value (if it
exists) of ^Acct(1,"ID").
GTM>w ^Acct(1,"ID")
1975
GTM>s ^Acct(1,"ID")=2011
The prior value of ^Acct(1,ID) was: 1975
3 $ZTRIggerop
$ZTRIggerop
Within trigger context, for SET (including MERGE and $INCREMENT()
operations), $ZTRIGGEROP has the value "S". For KILL, $ZTRIGGEROP has the
value "K" For ZKILL or ZWITHDRAW, $ZTRIGGEROP has the value "ZK".
3 $ZTSlate
$ZTSlate
$ZTSLATE allows you to specify a string that you want to make available in
chained or nested triggers invoked for an outermost transaction (when a
TSTART takes $TLEVEL from 0 to 1). You might use $ZTSLATE to accumulate
transaction-related information, for example $ZTOLDVAL and $ZTVALUE,
available within trigger context for use in a subsequent trigger later in
the same transaction. For example, you can use $ZTSLATE to build up an
application history or journal record to be written when a transaction is
about to commit.
You can SET $ZTSLATE only while a database trigger is active. GT.M clears
$ZTSLATE for the outermost transaction or on a TRESTART. However, GT.M
retains $ZTSLATE for all sub-transactions (where $TLEVEL>1).
Example:
TSTART () ; Implicitly clears $ZTSLAT
SET ^ACC(ACN1,BAL)=AMT ; Trigger sets $ZTSLATE=ACN_"|"
SET ^ACC(ACN2,BAL)=-AMT ; Trigger sets $ZTSLATE=$ZTSLATE_ACN_"|"
ZTRIGGER ^ACT("TRANS") ; Trigger uses $ZTSLATE to update transaction log
TCOMMIT
3 $ZTUPdate
$ZTUPdate
Within trigger context, for SET commands where the GT.M trigger specifies
a piece separator, $ZTUPDATE provides a comma separated list of piece
numbers of pieces that differ between the current values of $ZTOLDVAL and
$ZTVALUE. If the trigger specifies a piece separator, but does not specify
any pieces of interest, $ZTUPDATE identifies all changed pieces. $ZTUPDATE
is 0 in all other cases (that is: for SET commands where the GT.M trigger
does not specify a piece separator or for KILLs). Note that if an update
matches more than one trigger, all matching triggers see the same
$ZTOLDVAL at trigger entry but potentially different values of $ZTVALUE so
$ZTUPDATE could change due to the actions of each matching trigger even
though all matching triggers have identical -[z]delim and -piece
specifications.
Example:
+^trigvn -commands=Set -pieces=1;3:6 -delim="|" -xecute="Write !,$ZTUPDATE"
In the above trigger definition entry, $ZTUPDATE displays a comma
separated list of the changed piece numbers if on of the pieces of
interest: 1,3,4,5,or 6 are modified by the update.
GTM>write ^trigvn
Window|Table|Chair|Curtain|Cushion|Air Conditioner
GTM>set ^trigvn="Window|Dining Table|Chair|Vignette|Pillow|Air Conditioner"
4,5
Note that even though piece numbers 2,4 and 5 are changed, $ZTUPDATE
displays only 4,5 because the trigger is not defined for updates for the
second piece.
3 $ZTVAlue
$ZTVAlue
For SET, $ZTVALUE has the value assigned to the node by the explicit SET
operation. Modifying $ZTVALUE within a trigger modifies the eventual value
GT.M assigns to the node. Note that changing $ZTVALUE has a small
performance impact because it causes an additional update operation on the
node once all trigger code completes. If a node has multiple associated
triggers each trigger receives the current value of $ZTVALUE, however,
because the triggers run in arbitrary order, FIS strongly recommends no
more than one trigger change any given element of application data, for
example, a particular piece. For KILL and its variants, $ZTVALUE returns
the empty string. While GT.M accepts updates to $ZTVALUE within the
trigger code invoked for a KILL or any of its variants, it ultimately
discards any such value. Outside trigger context, attempting to SET
$ZTVALUE produces a SETINTRIGONLY error.
3 $ZTWOrmhole
$ZTWOrmhole
$ZTWORMHOLE allows you to specify a string up to 128KB of information you
want to make available during trigger execution. You can use $ZTWORMHOLE
to supply an application-context or process context to your trigger logic.
Because GT.M makes $ZTWORMHOLE available throughout the duration of the
process, you can access or update $ZTWORMHOLE both from inside and outside
a trigger.
$ZTWORMHOLE provides a mechanism to access information from a
process/application context that is otherwise unavailable in trigger
context. GT.M records any non-empty string value of $ZTWORMHOLE in the
GT.M database journal file as part of any update that invokes at least one
trigger which references $ZTWORMHOLE. GT.M also transmits any non-NULL
$ZTWORMHOLE value in the replication stream, thus providing the same
context to triggers invoked by MUPIP processes (either as part of the
replicating instance update process or as part of MUPIP journal
recovery/rollback). Therefore, whenever you use $ZTWORMHOLE in a trigger,
you create something like a wormhole for process context that is otherwise
NEWed in the run-time or non-existent in MUPIP.
Note that if trigger code does not reference $ZTMORMHOLE, GT.M does not
make it available to MUPIP (via the journal files or replication stream).
Therefore, if a replicating secondary has different trigger code than the
initiating primary (an unusual configuration) and the triggers on the
replicating node require information from $ZTWORMHOLE, the triggers on the
initiating node must reference $ZTWORMHOLE to ensure GT.M maintains the
data it contains for use by the update process on the replicating node.
While you can change $ZTWORMHOLE within trigger code, because of the
arbitrary ordering of triggers on the same node, such an approach requires
careful design and implementation. GTM allows $ZTWORMHOLE to be NEW'd.
NEWing $ZTWORMHOLE is slightly different from NEWing other ISVs/variables
in the sense that the former retains its original value whereas the latter
does not. However, like other NEWs, GT.M restores $ZTWORMHOLE's value when
the stack level pops.
The following table summarizes the read/write permissions assigned to all
trigger-related ISVs within trigger context and outside trigger context.
+------------------------------------------------------------------------+
| Intrinsic Special | Within Trigger | Notes |
| Variable | Context | |
|-------------------+----------------+-----------------------------------|
| | | Set to gtm_trigger_etrap or the |
| $ETRAP | Read / Write | empty string when entering |
| | | trigger context. |
|-------------------+----------------+-----------------------------------|
| $REFERENCE | Read only | Restored at the completion of a |
| | | trigger. |
|-------------------+----------------+-----------------------------------|
| $TEST | Read only | Restored at the completion of a |
| | | trigger. |
|-------------------+----------------+-----------------------------------|
| | | Always >=1 in trigger code; must |
| $TLEVEL | Read only | be the same as the completion of |
| | | processing a trigger as it was at |
| | | the start. |
|-------------------+----------------+-----------------------------------|
| $ZTNAME | Read only | Returns the trigger name. |
|-------------------+----------------+-----------------------------------|
| $ZTDATA | Read only | Shows prior state. |
|-------------------+----------------+-----------------------------------|
| $ZTLEVEL | Read only | Shows trigger nesting. |
|-------------------+----------------+-----------------------------------|
| $ZTOLDVAL | Read only | Shows the pre-update value. |
|-------------------+----------------+-----------------------------------|
| $ZTRAP | Read only - "" | Must use $ETRAP in trigger code. |
|-------------------+----------------+-----------------------------------|
| $ZTRIGGEROP | Read only | Shows the triggering command. |
|-------------------+----------------+-----------------------------------|
| $ZTUPDATE | Read only | Lists modified pieces (if |
| | | requested) for SET. |
|-------------------+----------------+-----------------------------------|
| $ZTVALUE | Read / Write | Can change the eventual applied |
| | | value for SET. |
|-------------------+----------------+-----------------------------------|
| | | Holds application context because |
| $ZTWORMHOLE | Read / Write | trigger code has no access to the |
| | | local variable context. |
|-------------------+----------------+-----------------------------------|
| | | Holds outermost transaction |
| $ZTSLATE | Read/ Write | context for chained or nested |
| | | triggers. |
+------------------------------------------------------------------------+
1 IO_Processing
IO Processing
This chapter describes the following topics which relate to input and
output processing:
* Input/Output Intrinsic Special Variables, and their Maintenance.
GT.M provides several intrinsic special variables that allow processes
to examine, and in some cases change, certain aspects of the
input/output (I/O) processing. The focus in this chapter is how GT.M
handles the standard ones, such as $IO, $X, $Y, and those that are
GT.M-specific (for example, $ZA, $ZB).
* Input/Output Devices
Each device type supported by GT.M responds to a particular subset of
deviceparameters, while ignoring others. Devices may be programmed in
a device-specific manner, or in a device-independent manner. This
chapter discusses each device type, and provides tables of their
deviceparameters.
* Input/Output Commands and their Deviceparameters
GT.M bases its I/O processing on a simple character stream model. GT.M
does not use any pre-declared formats. This chapter describes the GT.M
I/O commands OPEN, USE, READ, WRITE, and CLOSE.
OPEN, USE, and CLOSE commands accept deviceparameters, which are keywords
that permit a GT.M program to control the device state. Some
deviceparameters require arguments. The current ANSI standard for GT.M
does not define the deviceparameters for all devices. This chapter
includes descriptions of the GT.M deviceparameters in the sections
describing each command.
2 Using_Terminals
Using Terminals
A GT.M process assigns $PRINCIPAL to the UNIX standard input of the
process (for READ) and standard output (for WRITE). For a local
interactive process, $PRINCIPAL identifies the "terminal" from which the
user is signed on.
While all terminals support the CTRAP deviceparameter, only $PRINCIPAL
supports CENABLE. While CTRAP allows terminal input to redirect program
flow, CENABLE allows the terminal user to invoke the Direct Mode.
Directly connected printers often appear to GT.M as a terminal (although
printers generally do not provide input) regardless of whether the printer
is connected to the computer with a high speed parallel interface, or an
asynchronous terminal controller.
3 Set_Characteristics
Set Characteristics
GT.M does not isolate its handling of terminal characteristics from the
operating system environment at large. GT.M inherits the operating system
terminal characteristics in effect at the time the GT.M image is invoked.
When GT.M exits, the terminal characteristics known by the operating
system are restored.
However, if the process temporarily leaves the GT.M environment with a
ZSYSTEM command , GT.M does not recognize any changes to the terminal
characteristics left by the external environment. This may cause
disparities between the physical behavior of the terminal, and the
perceived behavior by GT.M.
UNIX enforces standard device security for explicit OPENs of terminals
other than the sign-in terminal ($PRINCIPAL). If you are unable to OPEN a
terminal, contact your system manager.
USE of a terminal causes the device driver to flush the output buffer.
This feature of the USE command provides routine control over the timing
of output, which is occasionally required. However, it also means that
redundant USE commands may induce an unnecessary performance penalty.
Therefore, FIS recommends restricting USE commands to redirecting I/O,
modifying deviceparameters, and initiating specifically required flushes.
The terminal input buffer size is fixed at 1024 on UNIX and a variable
read terminates after 1023 characters.
4 Set_TERM
Set TERM
The environment variable $TERM must specify a terminfo entry that
accurately matches the terminal (or terminal emulator) settings. Refer to
the terminfo man pages for more information on the terminal settings of
the platform where GT.M needs to run.
Some terminfo entries may seem to work properly but fail to recognize
function key sequences or position the cursor properly in response to
escape sequences from GT.M. GT.M itself does not have any knowledge of
specific terminal control characteristics. Therefore, it is important to
specify the right terminfo entry to let GT.M communicate correctly with
the terminal. You may need to add new terminfo entries depending on their
specific platform and implementation. The terminal (emulator) vendor may
also be able to help.
GT.M uses the following terminfo capabilities. The full variable name is
followed by the capname in parenthesis:
auto_right_margin(am), clr_eos(ed), clr_eol(el), columns(cols), cursor_address(cup), cursor_down(cud1),cursor_left(cub1), cursor_right(cuf1), cursor_up(cuu1), eat_newline_glitch(xenl), key_backspace(kbs), key_dc(kdch1),key_down(kcud1), key_left(kcub1), key_right(kcuf1), key_up(kcuu1), key_insert(kich1), keypad_local(rmkx),keypad_xmit(smkx), lines(lines).
GT.M sends keypad_xmit before terminal reads for direct mode and READs
(other than READ *) if EDITING is enabled. GT.M sends keypad_local after
these terminal reads.
3 Summary
Summary
The following tables provide a brief summary of deviceparameters for
terminals, grouped into related areas.
+----------------------------------------------------------------------+
| Error Processing Deviceparameters |
|----------------------------------------------------------------------|
| DEVICEPARAMETER | COMMAND | COMMENT |
|-----------------+---------+------------------------------------------|
| EXCEPTION=expr | O/U/C | Controls device-specific error handling. |
+----------------------------------------------------------------------+
+------------------------------------------------------------------------+
| Interaction Management Deviceparameters |
|------------------------------------------------------------------------|
| DEVICEPARAMETER | COMMAND | COMMENT |
|-----------------------+---------+--------------------------------------|
| | | Controls whether <CTRL-C> on |
| [NO]CENABLE | U | $PRINCIPAL causes GT.M to go to |
| | | direct mode. |
|-----------------------+---------+--------------------------------------|
| CTRAP=expr | U | Controls vectoring on trapped <CTRL> |
| | | characters. |
|-----------------------+---------+--------------------------------------|
| [NO]ESCAPE | U | Controls escape sequence processing. |
|-----------------------+---------+--------------------------------------|
| | | Controls interpretation by the |
| [NO]PASTHRU | U | operating system of special control |
| | | characters (for example <CTRL-B>). |
|-----------------------+---------+--------------------------------------|
| [NO]TERMINATOR[=expr] | U | Controls characters that end a READ |
+------------------------------------------------------------------------+
+------------------------------------------------------------------+
| Flow Control Deviceparameters |
|------------------------------------------------------------------|
| DEVICEPARAMETER | COMMAND | COMMENT |
|-----------------+---------+--------------------------------------|
| [NO]CONVERT | U | Controls forcing input to uppercase. |
|-----------------+---------+--------------------------------------|
| [NO]FILTER | U | Controls some $X, $Y maintenance. |
|-----------------+---------+--------------------------------------|
| FLUSH | U | Clears the typeahead buffer. |
|-----------------+---------+--------------------------------------|
| [NO]HOSTSYNC | U | Controls host's use of XON/XOFF. |
|-----------------+---------+--------------------------------------|
| [NO]READSYNC | U | Controls wrapping READs in XON/XOFF. |
|-----------------+---------+--------------------------------------|
| [NO]TTSYNC | U | Controls input response to XON/XOFF. |
|-----------------+---------+--------------------------------------|
| [NO]TYPEAHEAD | U | Controls unsolicited input handling. |
+------------------------------------------------------------------+
+------------------------------------------------------------------------+
| Screen Management Deviceparameters |
|------------------------------------------------------------------------|
| DEVICEPARAMETER | COMMAND | COMMENT |
|-------------------+---------+------------------------------------------|
| CLEARSCREEN | U | Clears from cursor to end-of-screen. |
|-------------------+---------+------------------------------------------|
| DOWNSCROLL | U | Moves display down one line. |
|-------------------+---------+------------------------------------------|
| [NO]ECHO | U | Controls the host echo of input. |
|-------------------+---------+------------------------------------------|
| ERASELINE | U | Clears from cursor to end-of-line. |
|-------------------+---------+------------------------------------------|
| [Z]LENGTH=intexpr | U | Controls maximum number of lines on a |
| | | page ($Y). |
|-------------------+---------+------------------------------------------|
| UPSCROLL | U | Moves display up one line. |
|-------------------+---------+------------------------------------------|
| [Z]WIDTH=intexpr | U | Controls the maximum width of an output |
| | | line ($X). |
|-------------------+---------+------------------------------------------|
| [Z][NO]WRAP | U | Controls handling of output lines longer |
| | | than the maximum width. |
|-------------------+---------+------------------------------------------|
| X=intexpr | U | Positions the cursor to column intexpr. |
|-------------------+---------+------------------------------------------|
| Y=intexpr | U | Positions the cursor to row intexpr. |
+------------------------------------------------------------------------+
O: Applies to the OPEN command
U: Applies to the USE command
C: Applies to the CLOSE command
2 Sequential_Files
Sequential Files
GT.M provides access to sequential files. These files allow linear access
to records. Sequential files are used to create programs, store reports,
and to communicate with facilities outside of GT.M.
3 Sequential_File_Pointers
Sequential File Pointers
Sequential file I/O operations use a construct called a file pointer. The
file pointer logically identifies the next record to read or write. OPEN
commands position the file pointer at the beginning of the file (REWIND)
or at the end-of-file (APPEND). APPEND cannot reposition a file currently
open. Because the position of each record depends on the previous record,
a WRITE destroys the ability to reliably position the file pointer to
subsequent records in a file. Therefore, by default (NOTRUNCATE), GT.M
permits WRITEs only when the file pointer is positioned at the end of the
file.
A file that has been previously created and contains data that should be
retained can also be opened with the device parameter APPEND.
If a device has TRUNCATE enabled, a WRITE issued when the file pointer is
not at the end of the file causes all contents after the current file
pointer to be discarded. This effectively moves the end of the file to the
current position and permits the WRITE.
3 Line_Terminators
Line Terminators
LF ($CHAR(10)) terminates the logical record for all M mode sequential
files, TRM, PIPE, and FIFO. For non FIXED format sequential files and
terminal devices for which character set is not M, all the standard
Unicode line terminators terminate the logical record. These are U+000A
(LF), U+0000D (CR), U+000D followed by U+000A (CRLF), U+0085 (NEL), U+000C
(FF), U+2028 (LS) and U+2029 (PS).
3 READ_/_WRITE_Operations
READ / WRITE Operations
The following table describes all READ and WRITE operations for STREAM,
VARIABLE, and FIXED format sequential files having automatic record
termination enabled (WRAP) or disabled (NOWRAP).
+------------------------------------------------------------------------+
| Command | WRAP or | STREAM or VARIABLE format file | FIXED format |
| | NOWRAP | behavior | file behavior |
|-----------+---------+---------------------------------+----------------|
| READ | | Write the entire argument, but | Similar to |
| format or | WRAP | anytime $X is about to exceed | VARIABLE but |
| WRITE or | | WIDTH: insert a <LF> character, | no <LF> |
| WRITE * | | set $X to 0, increment $Y | |
|-----------+---------+---------------------------------+----------------|
| | | Write up to WIDTH-$X (original | |
| | | $X) characters of the argument, | |
| | | update $X; | |
| | |---------------------------------| |
| | | | VARIABLE | |
| | | | ($X=WIDTH) : | |
| | | | Write up to | |
| | | STREAM | WIDTH-$X | |
| READ | | ($X=WIDTH) : | characters | |
| format or | | Write up to | unless WIDTH-$X | Same as |
| WRITE or | NOWRAP | WIDTH | equals 65535, | VARIABLE |
| WRITE * | | characters | in which case | |
| | | unless WIDTH | write all of | |
| | | equals 65535, | the argument. | |
| | | in which case | Write no more | |
| | | write all of | output to the | |
| | | the argument. | device until a | |
| | | | WRITE ! or a | |
| | | | SET $X makes $X | |
| | | | less than | |
| | | | WIDTH. | |
|-----------+---------+---------------------------------+----------------|
| | | | Write PAD |
| READ or | | Write <LF>, set $X to 0, | bytes to bring |
| WRITE ! | either | increment $Y | the current |
| | | | record to |
| | | | WIDTH |
|-----------+---------+---------------------------------+----------------|
| | | | Write PAD |
| | | | bytes to bring |
| | | | the current |
| WRITE # | either | Write <FF>,<LF>, set $X to 0, | record to |
| | | increment $Y | WIDTH, then a |
| | | | <FF> followed |
| | | | by WIDTH-1 PAD |
| | | | bytes |
|-----------+---------+---------------------------------+----------------|
| | | | After a WRITE, |
| | | | if $X >0, |
| | | | perform an |
| | | | implicit |
| | | | "WRITE !" |
| | | | adding PAD |
| | | | bytes to |
| CLOSE | either | After a WRITE, if $X > 0, Write | create a full |
| | | <LF> | record. If you |
| | | | need to avoid |
| | | | trailing PAD |
| | | | bytes set $X |
| | | | to 0 before |
| | | | closing a |
| | | | FIXED format |
| | | | file. |
|-----------+---------+---------------------------------+----------------|
| | | | Return WIDTH |
| | | Return characters up to | characters; no |
| | | $X=WIDTH, or until encountering | maintenance of |
| READ X | either | an <LF> or EOF. If <LF> | $X and $Y, |
| | | encountered, set $X to 0, | except that |
| | | increment $Y | EOF increments |
| | | | $Y |
|-----------+---------+---------------------------------+----------------|
| | | | Return |
| | | Return characters up to the | MIN(WIDTH, |
| | | first of $X=WIDTH or len | len) |
| READ | | characters, or encountering a | characters; no |
| X#len | either | <LF> or EOF; if up to len | maintenance of |
| | | characters or EOF update $X, | $X and $Y, |
| | | otherwise set $X to 0 and | except that |
| | | increment $Y | EOF increments |
| | | | $Y |
|-----------+---------+---------------------------------+----------------|
| | | | Return the |
| | | | code for one |
| | | Return the code for one | character, if |
| | | character and increment $X, if | EOF return -1; |
| READ *X | either | WIDTH=$X or <LF> encountered, | no maintenance |
| | | set $X=0, increment $Y; if EOF | of $X and $Y, |
| | | return -1 | except that |
| | | | EOF increments |
| | | | $Y |
+------------------------------------------------------------------------+
**Note**
o EOF == end-of-file; <FF>== ASCII form feed; <LF> == ASCII line feed;
o In M mode, and by default in UTF-8 mode PAD == <SP> == ASCII space.
o "READ format" in this table means READ ? or READ <strlit>
o A change to WIDTH implicitly sets WRAP unless NOWRAP follows in the
deviceparameter list
o In VARIABLE and STREAM mode, READ (except for READ *) never returns
<LF> characters
o In M mode, the last setting of RECORDSIZE or WIDTH for the device
determines WIDTH
o In UTF-8 mode, RECORDSIZE is in bytes and WIDTH is in characters and
the smaller acts as the WIDTH limit in the table.
o In UTF-8 mode, FIXED mode writes <SP> to the RECORDSIZE when the next
character won't fit.
o In UTF-8 mode, all READ forms do not return trailing PAD characters.
o In UTF-8 mode, all characters returned by all forms of FIXED mode READ
are from a single record.
o WRITE for a Sequential Disk (SD) device works at the current file
position, whether attained with APPEND, REWIND or SEEK.
o GT.M manages any BOM for UTF mode files by ensuring they are at the
beginning of the file and produces a BOMMISMATCH error for an attempt
to change the byte-ordering on OPEN for an existing file.
o An attempt to OPEN a non-zero length file WRITEONLY without either
NEWVERSION or TRUNCATE in UTF mode produces an OPENDEVFAIL due to the
fact that any existing BOM information cannot be verified.
o Note that with GT.M SD encryption, because of the state information
associated with encryption processing, encrypted files require the
file to be WRITEn or READ from the beginning rather than from an
arbitrary position.
3 _Binary_Files
Binary Files
To write a binary data file, open it with FIXED:WRAP:CHSET="M" and set $X
to zero before the WRITE to avoid filling the last record with spaces (the
default PAD byte value).
**Note**
With CHSET not "M", FIXED has a different definition. Each record is
really the same number of bytes as specified by RECORDSIZE. Padding bytes
are added as needed to each record.
Example:
bincpy(inname,outname); GT.M routine to do a binary copy from file named in argument 1 to file named in argument 2
;
new adj,nrec,rsize,x
new $etrap
set $ecode="",$etrap="goto error",$zstatus=""
set rsize=32767 ; max recordsize that keeps $X on track
open inname:(readonly:fixed:recordsize=rsize:exception="goto eof")
open outname:(newversion:stream:nowrap:chset="M")
for nrec=1:1 use inname read x use outname write x
eof
if $zstatus["IOEOF" do quit
. set $ecode=""
. close inname
. use outname
. set adj=$x
. set $x=0 close outname
. write !,"Copied ",$select((nrec-1)<adj:adj,1:((nrec-1)*rsize)+adj)," bytes from ",inname," to ",outname
else use $principal write !,"Error with file ",inname,":"
error
write !,$zstatus
close inname,outname
quit
3 Summary
Summary
The following tables provide a brief summary of deviceparameters for
sequential files grouped into related areas.
+----------------------------------------------------------------------+
| Error Processing Deviceparameters |
|----------------------------------------------------------------------|
| DEVICEPARAMETER | COMMAND | COMMENT |
|-----------------+---------+------------------------------------------|
| EXCEPTION=expr | O/U/C | Controls device-specific error handling. |
+----------------------------------------------------------------------+
+------------------------------------------------------------------------+
| File Pointer Positioning Deviceparameters |
|------------------------------------------------------------------------|
| DEVICEPARAMETER | COMMAND | COMMENT |
|-----------------+---------+--------------------------------------------|
| APPEND | O | Positions file pointer at EOF. |
|-----------------+---------+--------------------------------------------|
| REWIND | O/U/C | Positions file pointer at start of the |
| | | file. |
|-----------------+---------+--------------------------------------------|
| | | Positions the current file pointer to the |
| | | location specified in strexpr. The format |
| | | of strexpr is a string of the form |
| | | "[+|-]integer" where unsigned value |
| | | specifies an offset from the beginning of |
| | | the file, and an explicitly signed value |
| | | specifies an offset relative to the |
| SEEK=strexpr | O/U | current file position. For STREAM or |
| | | VARIABLE format, the positive intexpr |
| | | after any sign is a byte offset, while for |
| | | a FIXED format, it is a record offset. In |
| | | order to deal with the possible presence |
| | | of a Byte Order Marker (BOM), SEEK for a |
| | | FIXED format file written in a UTF |
| | | character set must follow at least one |
| | | prior READ since the device was created. |
+------------------------------------------------------------------------+
+------------------------------------------------------------------------+
| File Format Deviceparameters |
|------------------------------------------------------------------------|
| DEVICEPARAMETERS | COMMAND | COMMENT |
|--------------------+---------+-----------------------------------------|
| [NO]FIXED | O | Controls whether records have fixed |
| | | length. |
|--------------------+---------+-----------------------------------------|
| [Z]LENGTH=intexpr | U | Controls virtual page length. |
|--------------------+---------+-----------------------------------------|
| RECORDSIZE=intexpr | O | Specifies maximum record size. |
|--------------------+---------+-----------------------------------------|
| STREAM | O | Specifies the STREAM format. |
|--------------------+---------+-----------------------------------------|
| VARIABLE | O | Controls whether records have variable |
| | | length. |
|--------------------+---------+-----------------------------------------|
| [Z]WIDTH=intexpr | U | Controls maximum width of an output |
| | | line. |
|--------------------+---------+-----------------------------------------|
| [Z][NO]WRAP | O/U | Controls handling of records longer |
| | | than device width. |
+------------------------------------------------------------------------+
+------------------------------------------------------------------------+
| File Access Deviceparameters |
|------------------------------------------------------------------------|
| DEVICEPARAMETER | COMMAND | COMMENT |
|-----------------+---------+--------------------------------------------|
| DELETE | C | Specifies file be deleted by CLOSE. |
|-----------------+---------+--------------------------------------------|
| GROUP=expr | O/C | Specifies file permissions for other users |
| | | in the owner's group. |
|-----------------+---------+--------------------------------------------|
| NEWVERSION | O | Specifies GT.M create a new version of |
| | | file. |
|-----------------+---------+--------------------------------------------|
| OWNER=expr | O/C | Specifies file permissions for the owner |
| | | of file. |
|-----------------+---------+--------------------------------------------|
| [NO]READONLY | O | Controls read-only file access. |
|-----------------+---------+--------------------------------------------|
| RENAME=expr | C | Specifies CLOSE replace name of a disk |
| | | file with name specified by expression. |
|-----------------+---------+--------------------------------------------|
| SYSTEM=expr | O/C | Specifies file permissions for the owner |
| | | of the file (same as OWNER). |
|-----------------+---------+--------------------------------------------|
| [NO]TRUNCATE | O/U | Controls overwriting of existing data in |
| | | file. |
|-----------------+---------+--------------------------------------------|
| UIC=expr | O/C | Specifies file's owner ID. |
|-----------------+---------+--------------------------------------------|
| WORLD=expr | O/C | Specifies file permissions for users not |
| | | in the owner's group. |
+------------------------------------------------------------------------+
O: Applies to the OPEN command
U: Applies to the USE command
C: Applies to the CLOSE command
2 FIFO_Characteristics
FIFO Characteristics
FIFOs have most of the same characteristics as other sequential files,
except that READs and WRITEs can occur in any order.
The following characteristics of FIFO behavior may be helpful in using
them effectively.
With READ:
* If a READ is done while there is no data in the FIFO:
The process hangs until data is put into the FIFO by another process, or
the READ times out, when a timeout is specified.
The following table shows the result and the values of I/O status
variables for different types of READ operations on a FIFO device.
+------------------------------------------------------------------------+
| Operation | Result | $DEVICE | $ZA | $TEST | X | $ZEOF |
|-----------+---------------+------------+-----+-------+---------+-------|
| READ X:n | Normal | 0 | 0 | 1 | Data | 0 |
| | Termination | | | | Read | |
|-----------+---------------+------------+-----+-------+---------+-------|
| READ X:n | Timeout with | 0 | 0 | 0 | empty | 0 |
| | no data read | | | | string | |
|-----------+---------------+------------+-----+-------+---------+-------|
| | Timeout with | | | | Partial | |
| READ X:n | partial data | 0 | 0 | 0 | data | 0 |
| | read | | | | | |
|-----------+---------------+------------+-----+-------+---------+-------|
| | | 1,Device | | | empty | |
| READ X:n | End of File | detected | 9 | 1 | string | 1 |
| | | EOF | | | | |
|-----------+---------------+------------+-----+-------+---------+-------|
| READ X:0 | Normal | 0 | 0 | 1 | Data | 0 |
| | Termination | | | | Read | |
|-----------+---------------+------------+-----+-------+---------+-------|
| READ X:0 | No data | 0 | 0 | 0 | empty | 0 |
| | available | | | | string | |
|-----------+---------------+------------+-----+-------+---------+-------|
| | Timeout with | | | | Partial | |
| READ X:0 | partial data | 0 | 0 | 0 | data | 0 |
| | read | | | | | |
|-----------+---------------+------------+-----+-------+---------+-------|
| | | 1,Device | | | empty | |
| READ X:0 | End of File | detected | 9 | 1 | string | 1 |
| | | EOF | | | | |
|-----------+---------------+------------+-----+-------+---------+-------|
| READ X | Error | 1,<error | 9 | n/c | empty | 0 |
| | | signature> | | | string | |
+------------------------------------------------------------------------+
With WRITE:
* The FIFO device does non-blocking writes. If a process tries to WRITE
to a full FIFO and the WRITE would block, the device implicitly tries
to complete the operation up to a default of 10 times. If the
gtm_non_blocked_write_retries environment variable is defined, this
overrides the default number of retries. If the retries do not succeed
(remain blocked), the WRITE sets $DEVICE to "1,Resource temporarily
unavailable", $ZA to 9, and produces an error. If the GT.M process has
defined an EXCEPTION, $ETRAP or $ZTRAP, the error trap may choose to
retry the WRITE after some action or delay that might remove data from
the FIFO device.
* While it is hung, the process will not respond to <CTRL-C>.
With CLOSE:
* The FIFO is not deleted unless the DELETE qualifier is specified.
* If a process closes the FIFO with the DELETE qualifier, the FIFO
becomes unavailable to new users at that time.
* All processes currently USEing the FIFO may continue to use it, until
the last process attached to it CLOSES it, and is destroyed.
* Any process OPENing a FIFO with the same name as a deleted FIFO
creates a new one to which subsequent OPENs attach.
The default access permissions on a FIFO are the same as the mask settings
of the process that created the FIFO. Use the SYSTEM, GROUP, WORLD, and
UIC deviceparameters to specify FIFO access permissions. File permissions
have no affect on a process that already has the FIFO open.
3 FIFO_Deviceparameter_Summary
FIFO Deviceparameter Summary
The following table summarizes the deviceparameters that can be used with
FIFOs.
+------------------------------------------------------------------------+
| File Format Deviceparameters |
|------------------------------------------------------------------------|
| DEVICEPARAMETER | CMD | DESCRIPTION |
|--------------------+-----+---------------------------------------------|
| [NO]FIXED | O | Controls whether records have fixed length. |
|--------------------+-----+---------------------------------------------|
| [Z]LENGTH=intexpr | U | Controls the virtual page length. |
|--------------------+-----+---------------------------------------------|
| RECORDSIZE=intexpr | O | Specifies the maximum record size. |
|--------------------+-----+---------------------------------------------|
| VARIABLE | O | Controls whether records have variable |
| | | length. |
|--------------------+-----+---------------------------------------------|
| [Z]WIDTH=intexpr | U | Sets the device's logical record size and |
| | | enables WRAP. |
|--------------------+-----+---------------------------------------------|
| [Z][NO]WRAP | O/U | Controls the handling of records longer |
| | | than the device width. |
+------------------------------------------------------------------------+
+------------------------------------------------------------------------+
| File Access Deviceparameters |
|------------------------------------------------------------------------|
| DEVICEPARAMETER | CMD | COMMENT |
|-----------------+-----+------------------------------------------------|
| | | Specifies that the FIFO should be deleted when |
| | | the last user closes it. If specified on an |
| | | OPEN, DELETE is activated only at the time of |
| DELETE | C | the close. No new attachements are allowed to |
| | | a deleted FIFO and any new attempt to use a |
| | | FIFO with the name of the deleted device |
| | | creates a new device. |
|-----------------+-----+------------------------------------------------|
| GROUP=expr | O/C | Specifies file permissions for other users in |
| | | owner's group. |
|-----------------+-----+------------------------------------------------|
| [NO]READONLY | O | OPENs a device for reading only (READONLY) or |
| | | reading and writing (NOREADONLY). |
|-----------------+-----+------------------------------------------------|
| OWNER=expr | O/C | Specifies file permissions for owner of file. |
|-----------------+-----+------------------------------------------------|
| | | Specifies that CLOSE replace the name of a |
| RENAME=expr | C | disk file with the name specified by the |
| | | expression. |
|-----------------+-----+------------------------------------------------|
| SYSTEM=expr | O/C | Specifies file permissions for owner of file |
| | | (same as OWNER). |
|-----------------+-----+------------------------------------------------|
| UIC=expr | O/C | Specifies the file's owner ID. |
|-----------------+-----+------------------------------------------------|
| WORLD=expr | O/C | Specifies file permissions for users not in |
| | | the owner's group. |
+------------------------------------------------------------------------+
2 Using_Null_Devices
Using Null Devices
Null devices comprise of a collection of system purpose devices that
include /dev/null, /dev/zero, /dev/random, and /dev/urandom.
o /dev/null returns a null string on READ and sets $ZEOF
o /dev/random and /dev/urandom return a random value on READ and set
$ZEOF
o /dev/zero returns 0's on READ and does not set $ZEOF
A null device discards all output. GT.M maintains a virtual cursor
position for null devices as it does for terminals on output. Use null
devices for program testing and debugging, or for jobs that permit I/O to
be discarded under certain circumstances. For example, JOB processes must
have input and output devices associated with them, even though they do
not use them. Null devices are low overhead never-fail alternatives for
certain classes of I/O.
3 Null_Deviceparameter_Summary
Null Deviceparameter Summary
+------------------------------------------------------------------------+
| Null Deviceparameters |
|------------------------------------------------------------------------|
| DEVICEPARAMETER | COMMAND | COMMENT |
|------------------------------------------------------------------------|
| O: Applies to the OPEN command |
| |
| U: Applies to the USE command |
| |
| C: Applies to the CLOSE command |
|------------------------------------------------------------------------|
| | | Controls device-specified error |
| | | handling. For the null device this is |
| EXCEPTION=expr | O/U/C | only EOF handling and therefore |
| | | exceptions can never be invoked except |
| | | by a READ. |
|-------------------+---------+------------------------------------------|
| [NO]FILTER[=expr] | U | Controls some $X,$Y maintenance. |
|-------------------+---------+------------------------------------------|
| [Z]LENGTH=intexpr | U | Controls the length of the virtual page. |
|-------------------+---------+------------------------------------------|
| [Z]WIDTH=intexpr | U | Controls maximum size of a record. |
|-------------------+---------+------------------------------------------|
| [Z][NO]WRAP | O/U | Controls handling of records longer than |
| | | the maximum width. |
|-------------------+---------+------------------------------------------|
| X=intexpr | U | Sets $X to intexpr. |
|-------------------+---------+------------------------------------------|
| Y=intexpr | U | Sets $Y to intexpr. |
+------------------------------------------------------------------------+
3 Null_Device_Examples
Null Device Examples
This section contains examples of null device usage.
Example:
GTM>do ^runrep
runrep;
zprint ^runrep
set dev="/dev/null"
set hdr="********* REPORT HEADER ************"
open dev use dev
set x="" write hdr,!,$zdate($horolog),?30,$job,!
for set x=$order(^tmp($job,x)) quit:x="" do REPORT
quit
REPORT;
;large amount of code
quit;
This program produces a report derived from the information in the global
variable ^tmp. The unspecified routine REPORT may potentially contain a
large amount of code. To see that the basic program functions without
error, the programmer may discard the output involved in favor of watching
the function. To run the program normally, the programmer simply has to
change the variable dev to name another device and the routine REPORT
writes to the dev device.
Example:
job ^X:(in="/dev/null":out="/dev/null":err="error.log")
JOB ^X:(IN="/dev/null":OUT="/dev/null":ERR="error.log")
This example issues a GT.M JOB command to execute the routine ^X in
another process. This routine processes a large number of global variables
and produces no output. In the example, the JOBbed process takes its input
from a null device, and sends its output to a null device. If the JOBbed
process encounters an error, it directs the error message to error.log.
2 Using_PIPE_Devices
Using PIPE Devices
A PIPE device is used to access and manipulate the input and/or output of
a shell command as a GT.M I/O device. GT.M maintains I/O status variables
for a PIPE device just as it does for other devices. An OPEN of the device
starts a sub-process. Data written to the device by the M program is
available to the process on its STDIN. The M program can read the STDOUT
and STDERR of the sub-process. This facilitates output only applications,
such as printing directly from a GT.M program to an lp command; input only
applications, such as reading the output of a command such as ps; and
co-processing applications, such as using iconv to convert data from one
encoding to another.
A PIPE is akin to a FIFO device. Both FIFO and PIPE map GT.M devices to
UNIX pipes, the conceptual difference being that whereas a FIFO device
specifies a named pipe, but does not specify the process on the other end
of the pipe, a PIPE device specifies a process to communicate with, but
the pipes are unnamed. Specifically, an OPEN of a PIPE creates a
subprocess with which the GT.M process communicates.
A PIPE device is specified with a "PIPE" value for mnemonicspace on an
OPEN command.
**Note**
GT.M ignores the mnemonicspace specification on an OPEN of a previously
OPEN device and leaves the existing device with its original
characteristics.
3 PIPE_Characteristics
PIPE Characteristics
The following characteristics of PIPE may be helpful in using them
effectively.
With Read:
A READ with no timeout reads whatever data is available to be read; if
there is no data to be read, the process hangs until some data becomes
available.
A READ with a timeout reads whatever data is available to be read, and
returns; if there is no data to be read, the process waits for a maximum
of the timeout period, an integer number of seconds, for data to become
available (if the timeout is zero, it returns immediately, whether or not
any data was read). If the READ returns before the timeout expires, it
sets $TEST to TRUE(1); if the timeout expires, it sets $TEST to FALSE (0).
When the READ command does not specify a timeout, it does not change
$TEST. READ specifying a maximum length (for example, READ X#10 for ten
characters) reads until either the PIPE has supplied the specified number
of characters, or a terminating delimiter.
The following table shows the result and values of I/O status variables
for various READ operations on a PIPE device.
+------------------------------------------------------------------------+
| Operation | Result | $DEVICE | $ZA | $TEST | X | $ZEOF |
|-----------+---------------+------------+-----+-------+---------+-------|
| READ X:n | Normal | 0 | 0 | 1 | Data | 0 |
| | Termination | | | | Read | |
|-----------+---------------+------------+-----+-------+---------+-------|
| READ X:n | Timeout with | 0 | 0 | 0 | empty | 0 |
| | no data read | | | | string | |
|-----------+---------------+------------+-----+-------+---------+-------|
| | Timeout with | | | | Partial | |
| READ X:n | partial data | 0 | 0 | 0 | data | 0 |
| | read | | | | | |
|-----------+---------------+------------+-----+-------+---------+-------|
| | | 1,Device | | | empty | |
| READ X:n | End of File | detected | 9 | 1 | string | 1 |
| | | EOF | | | | |
|-----------+---------------+------------+-----+-------+---------+-------|
| READ X:0 | Normal | 0 | 0 | 1 | Data | 0 |
| | Termination | | | | Read | |
|-----------+---------------+------------+-----+-------+---------+-------|
| READ X:0 | No data | 0 | 0 | 0 | empty | 0 |
| | available | | | | string | |
|-----------+---------------+------------+-----+-------+---------+-------|
| | Timeout with | | | | Partial | |
| READ X:0 | partial data | 0 | 0 | 0 | data | 0 |
| | read | | | | | |
|-----------+---------------+------------+-----+-------+---------+-------|
| | | 1,Device | | | empty | |
| READ X:0 | End of File | detected | 9 | 1 | string | 1 |
| | | EOF | | | | |
|-----------+---------------+------------+-----+-------+---------+-------|
| READ X | Error | 1,<error | 9 | n/c | empty | 0 |
| | | signature> | | | string | |
+------------------------------------------------------------------------+
With WRITE:
The PIPE device does non-blocking writes. If a process tries to WRITE to a
full PIPE and the WRITE would block, the device implicitly tries to
complete the operation up to a default of 10 times. If the
gtm_non_blocked_write_retries environment variable is defined, this
overrides the default number of retries. If the retries do not succeed
(remain blocked), the WRITE sets $DEVICE to "1,Resource temporarily
unavailable", $ZA to 9, and produces an error. If the GT.M process has
defined an EXCEPTION, $ETRAP or $ZTRAP, the error trap may choose to retry
the WRITE after some action or delay that might remove data from the PIPE
device.
With WRITE /EOF:
WRITE /EOF to a PIPE device flushes, sets $X to zero (0) and terminates
output to the created process, but does not CLOSE the PIPE device. After a
WRITE /EOF, any additional WRITE to the device discards the content, but
READs continue to work as before. A WRITE /EOF signals the receiving
process to expect no further input, which may cause it to flush any output
it has buffered and terminate. You should explicitly CLOSE the PIPE device
after finishing all READs. If you do not want WRITE /EOF to flush any
pending output including padding in FIXED mode or a terminating EOL in
NOFIXED mode, SET $X=0 prior to the WRITE /EOF.
To avoid an indefinite hang doing a READ from a created process that
buffers its output to the input of the PIPE device, READ with timeout
(typically 0).
With CLOSE:
The CLOSE of a PIPE device prevents all subsequent access to the pipes
associated with the device. Unless the OPEN that created the device
specified INDEPENDENT, the process terminates. Note that any subsequent
attempt by the created process to read from its stdin (which would be a
closed pipe) returns an EOF and typical UNIX behavior would be to
terminate on such an event.
3 PIPE_Device_Examples
PIPE Device Examples
The following examples show the use of deviceparameters and status
variables with PIPE devices.
Example:
pipe1;
set p1="test1"
open p1:(shell="/bin/sh":comm="cat")::"PIPE"
for i=1:1:10 do
. use p1
. write i,":abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz ",!
. read x
. use $P
. write x,!
close p1
quit
This WRITEs 10 lines of output to the cat command and reads the cat output
back into the local variable x. The GT.M process WRITEs each line READ
from the PIPE to the principal device. This example works because "cat" is
not a buffering command. The example above would not work for a command
such as tr that buffers its input.
Example :
pipe3;
set p1="test1"
open p1:(shell="/bin/sh":command="tr -d e")::"PIPE"
for i=1:1:1000 do
. use p1
. write i,":abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz ",!
. read x:0
. if '+$device use $principal write x,!
use p1
write /EOF
for read x quit:$zeof use $principal write x,! use p1
close p1
quit
This shows the use of tr (a buffering command) in the created process for
the PIPE device. To see the buffering effect the GT.M process WRITEs 1000
lines to the PIPE device. Different operating systems may have different
buffer sizes. Notice the use of the r x:0 and the check on $DEVICE in the
loop. If $DEVICE is 0, WRITE x writes the data read to the principal
device. No actual READs complete, however, until tr reaches its buffer
size and writes to its stdout. The final few lines remain buffered by tr
after the process finishes the first loop. The GT.M process then issues a
WRITE /EOF to the PIPE causing tr to flush its buffered lines. In the
final for loop the GT.M process uses the simple form of READ x from the
PIPE followed by a WRITE of each line to the principal device until $zeof
becomes TRUE.
Example :
pipe4;
set a="test"
open a:(command="nestin":independent)::"PIPE"
use a
set key=$KEY
write "Show ntestin still running after CLOSE of a",!
write "The parent process of 1 shows the parent shell has exited after CLOSE of a"
read line1,line2
use $principal
write !,line1,!,line2,!,!
set k="ps -ef | grep -v grep | grep -v sh | grep -w '"_key_"' | awk '{print $2}'"
set b="getpid"
open b:(command=k:readonly)::"PIPE"
use b
read pid
close a
close b
set k2="ps -ef | grep -v grep | grep -v sh | grep -w '"_pid_"'"
set c="psout"
open c:(command=k2:writeonly)::"PIPE"
close c
quit
This demonstrates that the created process nestin keeps running as an
INDEPENDENT process after the GT.M process CLOSEs the pipe. This GT.M
process uses another PIPE device to return the process id of ntestin and
READ it into pid so that it may be killed by this or another process,
should that be appropriate.
**Note**
"nestin.c" is a program which reads from standard input and writes to
standard output until it see and EOF. It then loops for 300 1sec sleeps
doing nothing. The purpose of using independent is as a server process
which continues until it receives some other signal for termination.
Example:
GTM>kill ^a
GTM>zprint ^indepserver
indepserver;
read x
write "received = ",x,!
set ^quit=0
for do quit:^quit
. if $data(^a) write "^a = ",^a,!
. Hang 5
GTM>set a="test"
GTM>open a:(command="mumps -run ^indepserver>indout":independent)::"pipe"
GTM>use a
GTM>write "instructions",!
GTM>close a
GTM>zsystem "cat indout"
received = instructions
GTM>set ^a=1
GTM>zsystem "cat indout"
received = instructions
^a = 1
^a = 1
^a = 1
GTM>s ^quit=1
GTM>zsystem "cat indout"
received = instructions
^a = 1
^a = 1
^a = 1
^a = 1
GTM>
This is a simple example using a mumps process as a server.
Example:
pipe5;
set p1="test1"
set a=0
open p1:(shell="/bin/sh":command="cat":exception="goto cont1")::"PIPE"
set c=":abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz"
for i=1:1:10000 do
. use p1
. write i_c,!
. use $principal write i,!
use p1
write /EOF
for read x quit:$zeof use $principal write x,! use p1
close p1
quit
cont1
if $zeof quit
if a=0 set a=i/2
set z=$za
; use $device to make sure ztrap is caused by blocked write to pipe
set d=$device
if "1,Resource temporarily unavailable"=d DO
. use $p
. write "pipe full, i= ",i," $ZA = ",z,!
. set i=i-1
. use p1
. for j=1:1:a read x use $principal write j,"-",x,! use p1
quit
This demonstrates WRITEs to a PIPE device with blocking. The WRITE loop
has no READ to force the input pipe to fill up which blocks the cat
output, causing cat to stop reading its input, letting the pipe acting as
input on the PIPE device to fill up and creating the blocked condition.
When the process takes the $ZTRAP to cont1 it tests $DEVICE to determine
if the trap is caused by the full pipe. If so, it uses the for loop to
read half the number of lines output by the main loop. It decrements i and
returns to the original WRITE loop to retry the failed line and continue
with the WRITEs to the pipe. Depending upon the configuration of the
environment, it may trap several times before processing all lines.
3 PIPE_Deviceparameter_Summary
PIPE Deviceparameter Summary
The following table summarizes the PIPE format deviceparameters.
+------------------------------------------------------------------------+
| DEVICE PARAMETER | CMD | DESCRIPTION |
|--------------------+-----+---------------------------------------------|
| [NO]FIXED | O | Controls whether records have fixed length |
|--------------------+-----+---------------------------------------------|
| RECORDSIZE=intexpr | O | Specifies the maximum record size. |
|--------------------+-----+---------------------------------------------|
| VARIABLE | O | Controls whether records have variable |
| | | length. |
|--------------------+-----+---------------------------------------------|
| [Z]WIDTH=intexpr | U | Sets the device's logical record size and |
| | | enables WRAP. |
|--------------------+-----+---------------------------------------------|
| [Z][NO]WRAP | O/U | Controls the handling of records longer |
| | | than the device width. |
+------------------------------------------------------------------------+
The following table summarizes PIPE access deviceparamters.
+------------------------------------------------------------------------+
| | | Specifies the command string to execut in a |
| | | created process for the PIPE device. GT.M uses |
| COMMAND=string | o | the default searching mechanism of the UNIX shell |
| | | for creating the process and initiating its |
| | | command(s). |
|----------------+---+---------------------------------------------------|
| SHELL=string | o | Specifies the path to a shell to be used instead |
| | | of the default shell |
|----------------+---+---------------------------------------------------|
| | | Specifies a device handle for a return pipe to |
| | | which the created process writes any standard |
| STDERR=string | o | error output. The GT.M process can USE, READ, and |
| | | CLOSE it, but cannot WRITE to it. When the GT.M |
| | | process CLOSEs the PIPE device the PIPE device |
| | | CLOSEs STDERR, if still OPEN. |
|----------------+---+---------------------------------------------------|
| WRITEONLY | o | Specifies that the GT.M process may only WRITE to |
| | | the created process via the PIPE device. |
|----------------+---+---------------------------------------------------|
| | | Specifies that the GT.M process may only READ |
| | | from the created process via the PIPE device. |
| READONLY | o | Output from both the standard output and the |
| | | standard error output of the created process is |
| | | available unless STDERR is specified. |
|----------------+---+---------------------------------------------------|
| PARSE | o | Specifies that GT.M parse the COMMAND and issue |
| | | an OPEN exception for any invalid command. |
|----------------+---+---------------------------------------------------|
| INDEPENDENT | o | Specifies that the created process continues to |
| | | execute after the PIPE device is CLOSEd. |
+------------------------------------------------------------------------+
2 Using_Socket_Devices
Using Socket Devices
SOCKET devices are used to access and manipulate sockets. A SOCKET device
can have unlimited associated sockets. The default limit is 64. Set the
environment variable gtm_max_sockets to the number of maximum associated
sockets sockets that you wish to set for a GT.M process.
$VIEW("MAX_SOCKETS") returns the current value of the maximum number of
associated sockets.
At any time, only one socket from the collection can be the current
socket. If there is no current socket, an attempt to READ from, or WRITE
to the device, generates an error.
Sockets can be attached and detached from the collection of sockets
associated with a device. Detached sockets belong to a pseudo-device
called the "socketpool". A process can detach a socket from a device and
later attach it to the same device or another device.
**Caution**
Currently, GT.M does not produce an error if a socket is attached to a
device having a different CHSET.
**Note**
The GT.M socket device interface does not have the ability to pass sockets
between related or unrelated processes. Currently error trapping operates
on a device, rather than on a socket.
3 Message_Management
Message Management
From an application perspective, the transport layers used by a socket
device are stream-oriented, with no provisions for implicit application
messages. Therefore, the following are two common protocols used to
segment application messages.
1. One method is to use a, typically small, fixed length message
containing the length of the next, variable length, message. In GT.M a
simplistic writer might be:
Write $Justify($Length(x),4),x
A corresponding simplistic reader might be:
read len#4,x#len
The advantage of this approach is that the message content (the value
of x in the code fragments above) can contain any character. The
disadvantage is that detecting that the protocol has become
desynchronized is a problem.
2. The other common method is to place a delimiter between each
application message. The protocol breaks if a message ever includes a
delimiter as part of its content.
The SOCKET device provides a facility for recognizing delimiters because
parsing messages for delimiters is cumbersome.
3 Socket_Read_Operation
Socket Read Operation
TCP/IP is a stream-based protocol that guarantees that bytes arrive in the
order in which they were sent. However, it does not guarantee that they
will be grouped in the same packets.
If packets arrive infrequently, or at varying rates that are sometimes
slow, a short interval can waste CPU cycles checking for an unlikely
event. On the other hand, if the handling of packets is time critical, a
long interval can introduce an undesirable latency. If packets arrive in a
rapid and constant flow (an unusual situation), the interval doesn't
matter as much, as there is always something in the buffer for the READ to
work with. If you do not specify MOREREADTIME, SOCKET READ implements a
dynamic approach of using a longer first interval of 200 ms when it finds
no data, then shortening the interval to 10 ms when data starts to arrive.
If you specify an interval, the SOCKET device always uses the specified
interval and does not adjust dynamically.
Most SOCKET READ operations terminate as a result of the first condition
detected from (a) receipt of delimiters, (b) receipt of the maximum number
of characters, or (c) expiration of a timeout. Note that all of these
conditions are optional, and a specific READ may specify zero or more of
them. This section refers to these three conditions as "defined
terminating conditions". If a SOCKET READ is not subject to any of the
defined terminating conditions, it terminates after it has received at
least one character followed by an interval with no new characters. An
error can also terminate a READ. While none of the terminating conditions
is satisfied, the READ continues.
The following flowchart represents the logic of a SOCKET READ.
3 Socket_Read_Termination_Conditions
Socket Read Termination Conditions
A SOCKET READ operation terminates if any of the following conditions are
met:
+------------------------------------------------------------------------+
| Terminating | Argument Contains | $Device | $Key | $Test |
| Conditions | | | | |
|----------------+-------------------------+---------+-----------+-------|
| Error | Empty String | Error | Empty | 1 |
| | | String | String | |
|----------------+-------------------------+---------+-----------+-------|
| Timeout* | Data received before | Empty | Empty | 0 |
| | timeout | String | String | |
|----------------+-------------------------+---------+-----------+-------|
| Delimiter* | Data up to, but not | Empty | Delimiter | 1 |
| | including the delimiter | String | String | |
|----------------+-------------------------+---------+-----------+-------|
| Fixed Length | String of Fixed Length | Empty | Empty | 1 |
| Met* | | String | String | |
|----------------+-------------------------+---------+-----------+-------|
| Width | Full width String | Empty | Empty | 1 |
| | | String | String | |
|----------------+-------------------------+---------+-----------+-------|
| | One (1) to as many | | | |
| | characters as provided | | | |
| | by the transport | | | |
| | interface before | | | |
| | waiting for an interval | | | |
| | (in milliseconds) | | | |
| | specified by | | | |
| | MOREREADTIME with no | | | |
| | additional input. If | | | |
| | MOREREADTIME is not | | | |
| | specified, buffer is | | | |
| Buffer Emptied | checked every 200 | Empty | Empty | 1 |
| | milliseconds for its | String | String | |
| | first input and then | | | |
| | every 10 milliseconds | | | |
| | until no new input | | | |
| | arrives and no other | | | |
| | terminating conditions | | | |
| | are met. | | | |
| | | | | |
| | IF MOREREADTIME is | | | |
| | specified, READ uses | | | |
| | that value exclusively | | | |
| | for buffer checks. | | | |
+------------------------------------------------------------------------+
* denotes Defined Terminating Conditions
A non-fixed-length read, with no timeout and no delimiters (the sixth row
in the above table) requires a complex implementation of sequence of READs
to ensure a predictable result. This is because the transport layer stream
fragments delivered to the reader has only accidental correspondence with
the operations performed by the writer. For example, the following:
Write "Message 1","Message 2" is presented to the reader as the stream
"Message1Message2" but it can take from one (1) to 18 READ commands to
retrieve the entire stream.
Messaging protocol should implement READ in any of the following ways:
1. Use a delimiter to separate messages (generic READ and possibly a
larger value for MOREREADTIME).
2. Specify messages as <length, value> pairs (a pair of fixed-length
READs (READ # ) and possibly a larger value for MOREREADTIME).
3. Parse the bytes or characters as they come in (possibly a smaller
value for MOREADTIME)
3 Read_Command
Read Command
The READ command may be used to obtain data from a socket. A READ
operation terminates if any of the following are detected, in the order
specified below:
+------------------------------------------------------------------------+
| Terminating | Argument Contains | $Device | $Key |
| Condition | | | (Continued) |
|------------------+----------------------------+---------+--------------|
| Error | Empty string | Error | Empty string |
| | | string | |
|------------------+----------------------------+---------+--------------|
| Timeout | Data received before | Empty | Empty string |
| | timeout | string | |
|------------------+----------------------------+---------+--------------|
| Delimiter | Data up to, but not | Empty | Delimiter |
| | including the delimiter | string | string |
|------------------+----------------------------+---------+--------------|
| Fixed length met | String of fixed length | Empty | Empty string |
| | | string | |
|------------------+----------------------------+---------+--------------|
| | One (1) to as many | | |
| Buffer emptied | characters as happen to be | Empty | Empty string |
| | provided by the transport | string | |
| | interface | | |
+------------------------------------------------------------------------+
A non-fixed-length read, with no timeout and no delimiters requires a
complex implementation of sequence of READs to ensure a predictable
result. This is because the transport layer stream fragments delivered to
the reader has only accidental correspondence with the operations
performed by the writer. For example, the following
Write "Message 1","Message 2"
is presented to the reader as the stream "Message1Message2" but it can
take from one (1) to 18 READ commands to retrieve the entire stream.
3 WRITE_Command
WRITE Command
The WRITE command sends data to a socket.
The WRITE command for SOCKET devices accepts the following
controlmnemonics:
/L[ISTEN][(numexpr)]
where numexpr is in the range 1-5 and specifies the listen queue depth for
a listening socket. By default, an OPEN or USE with LISTEN immediately
sets the listen queue size to 1.
/W[AIT][(timeout)]
where timeout is a "numexpr" that specifies how long in seconds a server
waits for a connection or data to become available on one of the sockets
in the current Socket Device.
"WRITE !" inserts the character(s) of the first I/O delimiter (if any) to
the sending buffer. If "ZFF=expr" has been specified, "WRITE #" inserts
the characters of expr . Otherwise WRITE # has no effect. WRITE ! and
WRITE # always maintain $X and $Y in a fashion that emulates a terminal
cursor position except when the device is OPENed with a UTF CHSET because
the units for $X and $Y for terminals are in display columns while for
sockets they are in codepoints.
WRITE /PASS([targetpid],[timeout],handle[,handle]...)
WRIE /PASS allows a GT.M process to send DETACHed TCP or LOCAL sockets
(that is, sockets in the socket pool) to another GT.M process. The
receiving process should execute WRITE /ACCEPT to receive the socket.
WRITE /PASS and WRITE /ACCEPT require a current $IO that is a CONNECTed
(notLISTENing), LOCAL domain (not TCP), SOCKET device. GT.M issues
CONNSOCKREQ or LOCALSOCKREQ errors, respectively, when those conditions
are not met.
o If a numeric targetpid is specified, GT.M matches the value against
the process id ($JOB) of the process receiving the sockets. GT.M uses
a system service to perform this check on platforms that support it -
currently: Linux, AIX, and Solaris. On platforms which do not
implement the service (HP-UX), GT.M ignores the targetpid. If the pids
do not match, GT.M issues a PEERPIDMISMATCH error and does not
transfer the sockets.
o If a numeric timeout is specified, GT.M sets $TEST to 1 if the
transfer completes within the specified time, and otherwise sets $TEST
to 0 and does not transfer any of the sockets.
o Each handle specifies the name of a socket in the socket pool.
o On a successful transfer, GT.M closes the connection of the sending
process to the specified and sent sockets. In any case where the
transfer does not complete, GT.M retains all the sockets in the socket
pool of the sender.
WRITE /ACCEPT(.lvar,[sourcepid],[timeout][,[handle]]...)
WRITE /ACCEPT allows a GT.M process to receive a DETACHed TCP or LOCAL
sockets (that is, sockets in the socket pool) from another GT.M process .
The sending process should execute WRITE /PASS to send the socket. WRITE
/PASS and WRITE /ACCEPT require a current $IO that is a CONNECTed
(notLISTENing), LOCAL domain (not TCP), SOCKET device. GT.M issues
CONNSOCKREQ or LOCALSOCKREQ errors, respectively, when those conditions
are not met.
o lvar is an unsubscripted local variable name (lvn) which must be
passed by reference indicated with a period (".") prefix. On
successful completion, the specified unsubscripted lvn contains the
handles of the received socket, in the order they were sent, delimited
with a vertical bar ("|"). GT.M places the sockets in the socket pool,
so the process can ATTACH them to an appropriate SOCKET device for
subsequent use.
o If a numeric sourcepid is specified, GT.M matches the value against
the process id ($JOB) of the process sending the sockets. On platforms
which do not implement the service (HP-UX), GT.M ignores the
targetpid. If the pids do not match, GT.M issues a PEERPIDMISMATCH
error and does not transfer the sockets.
o If a numeric timeout is specified, GT.M sets $TEST to 1 if the
transfer completes within the specified time, and otherwise sets $TEST
to 0 and does not transfer the sockets.
o If any handles are specified, GT.M assigns the provided handle names
to the received sockets in the order in which they appear in the WRITE
/PASS of the sending process; empty items in the comma delimited
handle list act to preserve ordering. Where the list provides no
handle, the socket retains the handle provided by the sender. In
either case, if there is already a socket with the transfer handle
name in the socket pool, GT.M generates a new handle name for the
transfer socket. GT.M ignores excess handles specified beyond the
number of incoming sockets.
For both WRITE /PASS and WRITE /ACCEPT, $IO must be a SOCKET device, and
the current socket of the device must be CONNECTED(not LISTENING) and
LOCAL domain (not TCP).
SOCKET devices so not support mixing other READs and WRITEs with socket
passing on the same CONNECTED LOCAL socket and produce SOCKPASSDATAMIX
errors. The application may perform multiple WRITE /PASS and WRITE /ACCEPT
operations in either direction on the socket before issuing a CLOSE.
Note that the receiving process must establish desired deviceparameters
(e.g., DELIMITER) either by ATTACHing it to a SOCKET device that provides
the characteristic for all its sockets, or by a subsequent USE that
specifies the appropriate deviceparameter(s). GT.M transfers only the
socket connection itself, the socket handle, and buffered socket data (if
any).
3 Socket_Device_Operation
Socket Device Operation
Each socket may be in one of the following states (observable through
$KEY):
* CREATEindicates that the socket exists.
* ESTABLISHEDAfter a successful OPEN or USE with the CONNECT device
parameter or when GT.M was started with a socket as the $PRINCIPAL
device.
* LISTENINGindicates that the OPEN or USE with the LISTEN
deviceparameter was successful and a listen queue was established.
A listening socket used for accepting new connections goes through these
three states in one step with a single OPEN or USE. When a server does a
WRITE /WAIT, a client can establish a connection which creates a new
server socket. $KEY includes information about this new socket in the form
of CONNECT|handle|<address> where <address> is the IP address for TCP
sockets and path for LOCAL sockets.
Each socket may have one or more sockets waiting for either an incoming
connection or data available to READ (observable through $ZKEY). $ZKEY
contains semi-colon (";") separated list of entries detailing any waiting
sockets for a current SOCKET device.
For more information on $KEY and $ZKEY, refer to Chapter 8: "ISV".
3 Socket_Deviceparameter_Summary
Socket Deviceparameter Summary
+------------------------------------------------------------------------+
| Error Processing Deviceparameters |
|------------------------------------------------------------------------|
| DEVICEPARAMETER | COMMAND | COMMENT |
|-----------------+---------+--------------------------------------------|
| EXCEPTION=expr | O/U/C | Controls device-specific error handling. |
|-----------------+---------+--------------------------------------------|
| | | If $LENGTH(expr) and ("Tt"[$EXTRACT(expr)) |
| IOERROR=expr | O/U | then Error Trapping is enabled; otherwise |
| | | the application must check $DEVICE for |
| | | errors. |
+------------------------------------------------------------------------+
+------------------------------------------------------------------------+
| Format Deviceparameters |
|------------------------------------------------------------------------|
| DEVICEPARAMETER | COMMAND | COMMENT |
|--------------------+---------+-----------------------------------------|
| [NO]DELIMITER=expr | O/U | Specifies socket delimiter(s). |
|--------------------+---------+-----------------------------------------|
| [NO]FILTER=expr | U | Specifies character filtering for |
| | | socket output. |
|--------------------+---------+-----------------------------------------|
| LENGTH=expr, or | | Sets virtual page length for socket |
| | U | device. |
| ZLENGTH=expr | | |
|--------------------+---------+-----------------------------------------|
| ICHSET=expr | O/U/C | Specifies input character set |
|--------------------+---------+-----------------------------------------|
| OCHSET=expr | O/U/C | Specifies output character set |
|--------------------+---------+-----------------------------------------|
| [Z][NO]WRAP | O/U | Controls handling of records longer |
| | | than the device width. |
|--------------------+---------+-----------------------------------------|
| [Z]WIDTH=expr | U | Controls the maximum length of an |
| | | output message. |
|--------------------+---------+-----------------------------------------|
| Z[NO]FF=expr | O/U | Controls whether and what characters to |
| | | send in response to a WRITE #. |
+------------------------------------------------------------------------+
+------------------------------------------------------------------------+
| Socket Establishment/Disconnect Deviceparameters |
|------------------------------------------------------------------------|
| DEVICEPARAMETER | COMMAND | COMMENT |
|-----------------+---------+--------------------------------------------|
| CONNECT=expr | O/U | expr specifies protocol, and protocol |
| | | specific information |
|-----------------+---------+--------------------------------------------|
| LISTEN=expr | O/U | Similar to CONNECT but binds the socket |
| | | for subsequent /LISTEN and /WAIT |
+------------------------------------------------------------------------+
3 Socket_Device_Examples
Socket Device Examples
sockexamplemulti3.m demonstrates a use of $KEY and $ZKEY in a basic socket
I/O setup. It launches two jobs: a server process which opens a listening
socket and a client process which makes five connections to the server.
The server sends a message to each connection socket. Even-numbered client
sockets read the message partially but do not send a response back to the
server. Odd-numbered client sockets receive the full message and respond
to the server with the message "Ok.". The server reads two characters (but
the client sends three) and $ZKEY shows sockets with unread
characters.Please click Download sockexamplemulti3.m to download the
sockexamplemulti3.m program and follow instructions in the comments near
the top of the program file. You can also download sockexamplemulti3.m
from
http://tinco.pair.com/bhaskar/gtm/doc/books/pg/UNIX_manual/sockexamplemulti3.m.
You can start a GT.M process in response to a connection request made
using inetd/xinetd. The following example uses inetd/xinetd to implement a
listener which responds to connections and messages just as the prior
example.
In the configuration file for xinetd, define a new service called
gtmserver. Set socket_type to "stream" and wait should be "no" as in the
following snippet:
service gtmserver
{
disable = no
type = UNLISTED
port = 7777
socket_type = stream
wait = no
user = gtmuser
server = /path/to/startgtm
}
If you define the server in /etc/services, the type and port options are
not needed. For more information, the xinetd.conf man page for more
details.
If you are using inetd, a line should be added to /etc/inetd.conf with the
sockettype "stream", protocol "tcp", and the "nowait" flag should be
specified as in the example below, which assumes a gtmserver service is
defined in /etc/services:
gtmserver stream tcp nowait gtmuser /path/to/startgtm
In both of the above examples, "gtmuser" is the name of the user the
service gtmserver should be run as, and "/path/to/startgtm" is the name of
a script which defines some environment variables needed by GT.M before
starting it. Please check the man page for inetd.conf on your system since
the details may be slightly different.
The minimum variables are $gtm_dist which should specify the directory
containing the GT.M distribution and $gtmroutines. As an example:
#!/bin/bash
cd /path/to/workarea
export gtm_dist=/usr/local/gtm
export gtmroutines="/var/myApp/o(/var/myApp/r) $gtm_dist"
export gtmgbldir=/var/myApp/g/mumps.dat
$gtm_dist/mumps -r start^server
When start^server begins, the $PRINCIPAL device will already be connected
and $KEY will contain "ESTABLISHED|socket_handle|remote_ip_address". In
most cases, a USE should be executed to set various device parameters such
as delimiters.
The ZSHOW "D" command reports available information on both the local and
remote sides of a TCP socket including local and remove addresses and
ports.
0 OPEN SOCKET TOTAL=1 CURRENT=0
SOCKET[0]=h11135182870 DESC=0 CONNECTED ACTIVE NOTRAP
REMOTE=10.1.2.3@53731 LOCAL=10.2.3.4@7777
ZDELAY ZIBFSIZE=1024 ZIBFSIZE=0
2 I/O_Commands
I/O Commands
This section describes the following GT.M I/O commands:
* OPEN establishes a connection from a GT.M process to a device.
* USE declares a device as the current source of input and destination
for output.
* READ accepts characters from the current device into a global or local
variable.
* WRITE sends characters to the current device.
* CLOSE breaks the connection between a GT.M process and a device.
3 Open
Open
The OPEN command establishes a connection from a GT.M process to a device.
The format of the OPEN command is:
O[PEN][:tvexpr] expr[:[(keyword[=expr][:...])][:numexpr][:expr]][,...]
By default, when a device is unavailable, GT.M retries the OPEN
indefinitely at approximately one second intervals. A device is
unavailable when another process is using it exclusively, or when the
OPENing process does not have the resources left to open the device.
All other errors on OPEN raise an error condition and interrupt program
flow. A timeout is a tool that lets a GT.M routine regain program control
when a device remains unavailable. When the OPEN specifies a timeout, GT.M
keeps retrying until either the OPEN succeeds or the timeout expires.
If OPEN establishes a connection with a device before the timeout expires,
GT.M sets $TEST to TRUE (1). If the timeout expires, GT.M sets $TEST to
FALSE (0). If an OPEN command does not specify a timeout, the execution of
the command does not affect $TEST.
If a process has not previously OPENed a device, any deviceparameters not
supplied on the OPEN take their default values. When reOPENing a device
that it previously closed, a GT.M process restores all characteristics not
specified on the OPEN to the values the device had when it was last
CLOSEd, except with SD, FIFO, and PIPE. If you have a menu-driven
application that OPENs and CLOSEs devices based on user selections, take
care that every OPEN explicitly includes all deviceparameters important to
the application.
GT.M treats sequential disk files differently and uses defaults for
unspecified sequential disk file characteristics on every OPEN (i.e., GT.M
does not retain sequential disk file characteristics on a CLOSE).
If a process OPENs an already OPEN device, GT.M modifies any
characteristics that accept changes when a device is OPEN to reflect any
new deviceparameter specifications.
In UTF-8 mode, the OPEN command recognizes ICHSET, OCHSET, and CHSET as
three additional deviceparameters to determine the encoding of the the
input / output devices.
In M mode, the OPEN command ignores ICHSET, OCHSET, CHSET, and PAD device
parameters.
If an I/O device uses a multi-byte character encoding, every READ and
WRITE operation of that device checks for well-formed characters according
to the specified character encoding with ICHSET or OCHSET. If the I/O
commands encounter an illegal sequence of bytes, they always trigger a
run-time error; a VIEW "NOBADCHAR" does not prevent such errors. Strings
created by $ZCHAR() and other Z equivalent functions may contain illegal
sequences. The only way to input or output such illegal sequences is to
specify character set "M" with one of these deviceparameters.
4 Examples_of_OPEN
Examples of OPEN
Example:
set sd="report.dat" open sd:newversion
This OPENs a NEWVERSION of a sequential disk file named report.dat for
both read and write access.
4 OPEN_Deviceparameters
OPEN Deviceparameters
5 APPEND
APPEND
APPEND Applies to: SD
APPEND Applies to: Sequential Files
Positions the file pointer at the end-of-file. This deviceparameter only
affects the device on the first OPEN command or OPEN command if the file
is CLOSEd NODESTROY. Re-OPENing an already OPEN device with this
deviceparameter has no effect. By default, OPEN sets the file pointer to
the beginning-of-file.
**Note**
If an APPEND is combined with a SEEK deviceparameter the APPEND is done
first - regardless of deviceparameter order.
Example:
set sd="foo.txt"
open sd:(append:recordsize=70:wrap)
use sd
This example open file foo.txt and positions the file pointer at the end
of the file.
5 ATTACH
ATTACH
ATTACH=expr Applies to: SOC
Attach=expr Applies to: Socket Device
ATTACH assigns expr as the handle name to the newly created socket. When
ATTACH is used and one of LISTEN or CONNECT is specified on the same OPEN,
the value of expr becomes the identifier of the newly created socket. If
neither LISTEN nor CONNECT is specified, ATTACH is ignored.
Example:
open tcpdev:(ichset="M":connect=hostname_":"_portno_":TCP":attach="client"):timeout:"SOCKET"
This example uses the ATTACH deviceparameter to specify "client" as the
identifier of the newly created socket. Note that GT.M recognizes ICHSET
only in UTF-8 mode.
5 CHSET
CHSET
CHSET=expr Applies to: All devices
Establishes a common encoding for both input and output devices for the
device being OPENed in UTF-8 mode. The value of the expression can be M,
UTF-8, UTF-16, UTF-16LE, or UTF-16BE.
5 CONNECT
CONNECT
CONNECT=expr Applies to: Socket Device
Creates a client connection with a server, which is located by the
information provided by expr. A new socket is allocated for the client
connection and is made the current socket for the device, if the operation
is successful.
expr specifies the protocol and the protocol-specific information.
Currently, GT.M supports TCP/IP and LOCAL (also known as UNIX domain)
socket protocols. For TCP/IP sockets, specify expr in the form of
"<host>:<port>:TCP", where host is an IPv4 or IPv6 address optionally
encapsulated by square-brackets ([]) like "127.0.0.1", "::1",
"[127.0.0.1]", or "[::1]" or a IPv4 or IPv6 hostname like
server.fis-gtm.com. When a hostname is specified, GT.M uses the IP version
of the first address returned by DNS:
o that is supported by the operating system, and
o for which a network interface exists.
For LOCAL sockets, specify expr in the form of "<pathname>:LOCAL", where
<pathname> is the name of the file to be used for communication.
<pathname> may contain a dollar sign ($) followed by the name of an
environment variable which GT.M expands in the same way as the device name
for a sequential file. The maximum allowed length of the expanded path
name depends on the OS.
For LOCAL sockets, CONNECT attempts to open the specified file. If it
doesn't exist or there is no listener, CONNECT retries until it succeeds
or a specified timeout expires.
**Note**
CONNECT is not compatible with LISTEN.
If the OPEN does not specify a timeout, a SOCKET OPEN waits for the
connection to complete or an event that terminates the attempt.
Example:
open tcpdev:(connect=hostname_":"_portno_":TCP":attach="client":ioerror="TRAP"):timeout:"SOCKET"
This example establishes a client connect with the server using the
connection string in the format of "hostname:port:TCP".
5 DELIMITER
DELIMITER
[NO]DELIMITER=expr Applies to: SOC
DELIMITER establishes or replaces the list of delimiters used by the newly
created socket. The default is NODELIMITER. The delimiter list on a
preexisting device remains the same until it is explicitly replaced or
deleted.
expr is a string where the following characters have special
interpretation:
**Note**
expr "ab:/:://:bc" is interpreted as four delimiters, which are "ab", ":",
"/", and "bc". One socket can have 0-64 delimiters and each delimiter can
contain 1-64 characters.
Example:
open tcpdev:(connect=host_":"_portno_":TCP":delim=$c(13):attach="client"):timeout:"SOCKET"
This command specifies $CHAR(13) as the delimiter for the socket tcpdev.
5 EXCEPTION
EXCEPTION
EXCEPTION=expr Applies to: All devices
Defines an error handler for an I/O device. The expression must contain a
fragment of GT.M code (for example, GOTO ERRFILE) that GT.M XECUTEs when
GT.M detects an error, or an entryref to which GT.M transfers control, as
appropriate for the current gtm_ztrap_form.
A device EXCEPTION gets control after a non-fatal device error and
$ETRAP/$ZTRAP get control after other non-fatal errors.
For more information on error handling, refer to Chapter 13: "Err
Processing".
Example:
open file:(EXCEPTION="s err=""open"" do error")
This example sets the following code to XECUTE when there is an error
while opening the file.
set err="open"
do error
5 EMPTERM
EMPTERM
[NO]EMPT[ERM] Applies to: TRM
Allows an "Erase" character on an empty input line to terminate a READ or
READ # command. The default is NOEMPTERM. The gtm_principal_editing
environment variable specifies the initial setting of [NO]EMPTERM. The
TERMINFO specified by the current value of the TERM environment variable
defines capnames values "kbs" and/or "kdch1" with character sequences for
"Erase." If "kbs" or "kdch1" are multi-character values, you must also
specify the ESCAPE or EDIT deviceparameters for EMPTERM recognition.
The erase character as set and shown by stty also terminates a READ
command with an empty input line. You can set this erase character to
various values using the stty shell command. Typical values of an erase
character are <CTRL-H> and <CTRL-?>. Characters set and shown with stty
setting must match what the terminal emulator sends.
The environment variable TERM must specify a terminfo entry that matches
both what the terminal (or terminal emulator) sends and expects.
5 FIFO
FIFO
FIFO Applies to: FIFO
FIFO Applies to: FIFO
Specifies that the device for the OPEN is a FIFO name. GT.M creates the
FIFO if it does not already exist and if the process has adequate
privileges. However, in the event that the process does not have adequate
privileges, the process generates a run-time error. A process does not
require any special privileges to OPEN an existing FIFO. The FIFO needs to
be readable (or writeable) just like any other file.
Example:
open file:(fifo:read:recordsize=1048576):100
5 FIXED
FIXED
[NO]FIXED Applies to: SD FIFO PIPE
[NO]FIXED Applies to: SD FIFO PIPE
Selects a fixed-length record format for sequential disk files. FIXED does
not specify the actual length of a record. Use RECORDSIZE to specify the
record length.
NOFIXED specifies a variable-length record format for sequential disk
files. NOFIXED is a synonym for VARIABLE. FIXED is incompatible with
STREAM and VARIABLE. By default, records have VARIABLE length record
format.
**Note**
FIXED length records do not implicitly use embedded record terminators
such as line feeds.
In UTF-8 mode, GT.M I/O enforces a more record-oriented view of the file,
treating each record as RECORDSIZE bytes long. Note that a Unicode
code-point never splits across records. If a multi-byte character (when
CHSET is UTF-8) or a surrogate pair (when CHSET is UTF-16) does not fit
into the record (either logical as given by WIDTH or physical as given by
RECORDSIZE), the WRITE command uses the byte values as specified by the
PAD deviceparameter to fill the physical record. A combining character may
end up in the subsequent record if it does not fit in the current record.
**Note**
PAD is effective only for devices opened with a Unicode CHSET. In M mode
PAD is always <SP>
Example:
GTM>do ^fixedex
fixedex;
zprint ^fixedex
set file="fix.txt"
open file:(newversion:fixed:recordsize=4)
use file
write "Hello, World",!
close file
set file="fixnowrap.txt"
open file:(newversion:fixed:recordsize=4:nowrap)
use file
write "Hel",!
write "lo, World",! ; This writes only 'lo, '
close file
zsystem ("more fix*.txt")
zsystem ("od -cb fix.txt")
zsystem ("od -cb fixnowrap.txt")
quit
::::::::::::::
fix.txt
::::::::::::::
Hello, World
::::::::::::::
fixnowrap.txt
::::::::::::::
Hel lo,
0000000 H e l l o , W o r l d
110 145 154 154 157 054 040 127 157 162 154 144
0000014
0000000 H e l l o ,
110 145 154 040 154 157 054 040
0000010
Example:
GTM>zprint ^gtmcp
gtmcp ; Copy a binary file using GT.M
new dest,line,max,src
if 2>$length($zcmdline," ") write "$gtm_dist/mumps -r source target",!
set dest=$piece($zcmdline," ",2)
set src=$piece($zcmdline," ",1)
set max=1024*1024 ; the maximum GT.M string size
open src:(readonly:FIXED:WRAP:CHSET="M") ;
open dest:(newversion:FIXED:WRAP:CHSET="M") ; use FIXED format because it does not insert carriage control characters after $X reaches its maximum value.
for use src read line#max quit:$zeof use dest write line
close src
use dest
set $x=0
close dest
quit
This example copies a binary file using GT.M.
5 FOLLOW
FOLLOW
[NO]FOLLOW Applies to: SD
Configures READ to return only when it has a complete record or reaches
any specified timeout; it waits for more input rather than terminating on
an EOF (end-of-file) condition.
The USE command can switch a device from NOFOLLOW to FOLLOW or from FOLLOW
to NOFOLLOW. This provides a READ mode of operation similar to a tail -f
in UNIX.
5 GROUP
GROUP
GROUP=expr Applies to: SOC(LOCAL) SD FIFO
Specifies access permission on a UNIX file for other users in the file
owner's group. The expression is a character string evaluating to null or
to any combination of the letters RWX, indicating respectively Read,
Write, and eXecute access. When permission controlling deviceparameters
(OWNER,GROUP,WORLD) appears on an OPEN of a new file, any user category
(OWNER, SYSTEM, WORLD), that is not explicitly specified is given the
default access permissions. When any one of these deviceparameters appears
on an OPEN of an existing device, any user category that is not explicitly
specified remains unchanged.
In order to modify file security, the user who issues the OPEN must have
ownership.
If none of GROUP, SYSTEM, OWNER, or WORLD are specified on OPEN, GT.M does
not modify the permissions on an existing file and new files are created
using the standard UNIX rules.
Example:
open "test52.txt":(append:group="rw")
This examples open file test52.txt in append mode with Read Write group
access. Note that the user who opens file text52.txt must have ownership
permissions for it.
5 ICHSET
ICHSET
ICHSET=expr Applies to: All devices
Establishes the character encoding of the input device being OPENed in the
UTF-8 mode. The value of the expression can be M, UTF-8, UTF-16, UTF-16LE,
or UTF-16BE. In M mode, ICHSET has no effect.
If ICHSET is not specified, GT.M assumes UTF-8 as the default character
set for input from the device.
If expr is set to a value other than M, UTF-8, UTF-16, UTF-16LE or
UTF-16BE, GT.M produces a run-time error. UTF-16, UTF-LE, and UTF-16BE are
not supported for $Principal and Terminal devices.
**Note**
ICHSET is a deviceparameter of the OPEN command and not the USE command.
Since GT.M implicitly OPENs $PRINCIPAL before any application code is
executed, ICHSET does not apply to $Principal.
5 INDEPENDENT
INDEPENDENT
INDEPENDENT Applies to: PIPE
The INDEPENDENT deviceparameter specifies that the newly created process
will not be terminated by the CLOSE of the device. The input and output of
INDEPENDENT processes should be handled in such a way that it runs
independently even after the CLOSE of the device. By default, CLOSE
terminates the process associated with the PIPE device.
5 IKEY
IKEY
Applies to: SD, PIPE, and FIFO
IKEY allows the use of a seperate key for READ to a device; for example,
when a GT.M process is an element of a UNIX pipe. The format of the IKEY
deviceparameter is:
IKEY="key_name [IV]"
key_name is case-sensitive and must match a key name in the "files"
section of the gtmcrypt_config file. The optional IV specifies an
initialization vector to use for encryption and decryption.
For more information, refer to the description of KEY deviceparameter of
OPEN or USE.
5 IOERROR
IOERROR
IOERROR=expr Applies to: SOC
Enables exception handling in socket devices. expr specifies the I/O error
trapping mode. A value equal to "TRAP" specifies that I/O errors on a
device raise error conditions. A value equal to "NOTRAP", or when IOERROR
is not specified, indicates that I/O error on a device does not raise
error conditions.
**Note**
The IOERROR setting is associated with sockets while EXCEPTION is
associated with the SOCKET device. In other words, IOERROR can be turned
on or off for each of the sockets associated with a SOCKET device but
there is only one EXCEPTION value which is used for all the sockets.
Example:
open sock:(connect=host_":"_port_":TCP":delim=$char(13,10):ioerror="TRAP")::"SOCKET"
This example opens a socket connection and specifies that I/O errors on
the device raises error conditions.
5 LISTEN
LISTEN
LISTEN=expr Applies to: SOC
A new socket is allocated to listen for a connection. It is made the
current socket for the device, if the operation is successful. Upon
successful completion, $KEY is set to the format of
"LISTENING|<socket_handle>|{<portnumber>|</path/to/LOCAL_socket>}"
otherwise, $KEY is assigned the empty string.
expr specifies the protocol and protocol specific information. Currently,
GT.M supports TCP/IP and LOCAL (also known as UNIX domain) socket
protocols. For TCP/IP sockets, specify expr in the form of "<port>:TCP".
If <port>=0 is specified, the system chooses the port for the TCP/IP
socket.
For LOCAL sockets:
o Specify expr in the form of "<pathname>:LOCAL", where <pathname> is
the name of the file to be used for communication. <pathname> may
contain a dollar sign ($) followed by the name of an environment
variable which GT.M expands in the same way as the device name for a
sequential file. The maximum allowed length of the expanded path name
depends on the OS.
o LISTEN creates the file if it doesn't exist. If the OPEN command
specifies the NEWVERSION deviceparameter, the file specified by the
pathname exists, and is a socket file, that file is deleted and GT.M
creates a new file.
o LISTEN with an OPEN processes the GROUP, OWNER, SYSTEM, WORLD, UIC,
and NEWVERSION deviceparameters the same as OPEN for sequential files.
5 MOREREADTIME
MOREREADTIME
MOREREADTIME=intexpr Applies to: SOC
MOREREADTIME specifies the polling interval (in milliseconds) that a
SOCKET device uses to check for arriving packets.
With no MOREREADTIME specified, SOCKET READ implements a dynamic approach
of using a longer first interval of 200 ms when it finds no data, then
shortening the interval to 10 ms when data starts to arrive.
If an interval is specified, the SOCKET device always uses the specified
interval and doesn't adjust dynamically. This applies to any SOCKET READ.
If a SOCKET READ is not subject to any of the defined terminating
conditions, it terminates either after it has at least one character
followed by an interval with no new packets, or reading 1,048,576 bytes.
Example:
Use tcpdev:morereadtime=200
This example specifies that all READs for socket device tcpdev must wait
for 200 milliseconds for input.
5 NEWVERSION
NEWVERSION
NEWVERSION Applies to: SD FIFO SOC(LOCAL)
The NEWVERSION deviceparameter assures that when an existing file is used,
it is empty upon the OPEN.
By default, if any version of the file exists, OPEN accesses the current
version. If no version of the file exists, OPEN without READONLY creates a
new file.
Example:
GTM>file1="foo.txt"
GTM>open file1:newversion:recordsize=5000
GTM>
This example creates a new version of sequential file foo.txtwith
RECORDSIZE of 5000 bytes.
Example:
GTM>set delim=$c(13)
GTM>set tcpdev="server$"_$j,timeout=30
GTM>open tcpdev:(LISTEN="local.socket"_":LOCAL":delim=$c(13):attach="server":newversion):timeout:"SOCKET"
This example deletes the old local.socket file (if it exists) and creates
a new LISTENING local.socket file.
5 OCHSET
OCHSET
OCHSET=expr Applies to: All devices
Establishes the character encoding of the output device being OPENed in
the UTF-8 mode. The value of the expression can be M, UTF-8, UTF-16,
UTF-16LE, or UTF-16BE. In M mode, OCHSET has no effect.
If *CHSET is not specified, GT.M assumes UTF-8 as the default character
set for all the input / output devices.
If expr is set to a value other than M, UTF-8, UTF-16, UTF-16LE or
UTF-16BE, GT.M produces a run-time error. UTF-16, UTF-LE, and UTF-16BE are
not supported for $Principal and Terminal devices.
**Note**
OCHSET is a deviceparameter of the OPEN command not the USE command. Since
GT.M implicitly OPENs $PRINCIPAL before any application code is executed,
OCHSET does not apply to $Principal.
Example:
GTM>SET file1="mydata.out"
GTM>SET expr="UTF-16LE"
GTM>OPEN file1:(ochset=expr)
GTM>SET DS=$CHAR($$FUNC^%HD("0905"))_$CHAR($$FUNC^%HD("091A"))
GTM>SET DS=DS_$CHAR($$FUNC^%HD("094D"))_$CHAR($$FUNC^%HD("091B"))_$CHAR($$FUNC^%HD("0940"))
GTM>USE file1 WRITE DS,!
GTM>CLOSE file1
This example opens a new file called mydata.out and writes Devanagari
characters in the UTF-16LE encoding.
5 OWNER
OWNER
OWNER=expr Applies to: SOC(LOCAL) SD FIFO
Specifies access permission on a UNIX file for the owner of the file. The
expression is a character string evaluating to null or to any combination
of the letters RWX, indicating Read, Write, and eXecute access. When any
one of these deviceparameters appears on an OPEN of a new file, any user
category that is not explicitly specified is given the default mask. When
any one of these deviceparameters (OWNER, GROUP, , WORLD) appears on an
OPEN of an existing file, any user category that is not explicitly
specified remains unchanged.
To modify file security, the user who issues the OPEN must have ownership.
If none of GROUP, SYSTEM, OWNER, or WORLD are specified on OPEN, GT.M does
not modify the permissions on an existing file and new files are created
using the standard UNIX rules.
Example:
open "test49.txt":(newversion:owner="rw":group="rw":world="rw")
This example opens a new version of test49.txt with Read Write acess for
the owner.
5 PAD
PAD
PAD=expr Applies to: SD FIFO PIPE
For FIXED format sequential files when the character set is not M, if a
multi-byte character (when CHSET is UTF-8) or a surrogate pair (when CHSET
is UTF-16) does not fit into the record (either logical as given by WIDTH
or physical as given by RECORDSIZE) the WRITE command uses bytes with the
value specified by the PAD deviceparameter to fill out the physical
record. READ ignores the pad bytes when found at the end of the record.
The value for PAD is given as an integer in the range 0-127 (the ASCII
characters). PAD is always a byte value and the default is $ZCHAR(32) or
[SPACE].
In UTF-8 mode, there are three cases that cause GT.M to insert PAD
characters when WRITEing. When READing GT.M attempts to strip any PAD
characters. This stripping only works properly if the RECORDSIZE and PAD
are the same for the READ as when the WRITEs occurred. WRITE inserts PAD
characters when:
1. The file is closed and the last record is less than the RECORDSIZE.
Records are padded (for FIXED) by WRITE ! as well as when the file is
closed.
2. $X exceeds WIDTH before the RECORDSIZE is full.
3. The next character won't fit in the remaining RECORDSIZE.
**Note**
In all UTF-16 character sets, RECORDSIZE must be even and PAD bytes occupy
two bytes with the high order byte zero.
Example:
GTM>do ^padexample
padexample
zprint ^padexample
set a="************"
set encoding="UTF-8"
set filename="bom"_encoding_".txt"
open filename:(newversion:fixed:record=8:pad=66:chset=encoding)
use filename
write a
close filename
halt
$ cat bomUTF-8.txt
**BB**BB**BB**BB**BB**
$ od -tcd1 bomUTF-8.txt
0000000 344 270 273 350 246 201 B B 351 233 250 345 234 250 B B
-28 -72 -69 -24 -90 -127 66 66 -23 -101 -88 -27 -100 -88 66 66
0000020 350 245 277 347 217 255 B B 347 211 231 345 201 234 B B
-24 -91 -65 -25 -113 -83 66 66 -25 -119 -103 -27 -127 -100 66 66
0000040 347 225 231 345 234 250 B B 345 271 263 345 216 237
-25 -107 -103 -27 -100 -88 66 66 -27 -71 -77 -27 -114 -97 32 32
0000060
In this example, the local variable a is set to a string of three-byte
characters. PAD=66 sets padding byte value to $CHAR(66)
5 PARSE
PARSE
PARSE Applies to: PIPE
The PARSE deviceparameter invokes preliminary validation of the COMMAND
value. When debugging, PARSE provides more accessible diagnosis for
COMMAND values. By default, OPEN does not validate command values before
passing them to the newly created process. PARSE has certain limitations,
which may, or may not map to, those of the shell.
5 RECORDSIZE
RECORDSIZE
RECORDSIZE=intexpr Applies to: SD FIFO PIPE
Overrides the default record size for a disk.
If the character set is M, RECORDSIZE specifies the initial WIDTH.
The RECORDSIZE of a fixed length record for a GT.M sequential disk device
is always specified in bytes, rather than characters.
For all UTF-16 CHSET values, RECORDSIZE must be even and PAD characters
each occupy two bytes in the record.
The maximum size of intexpr is 1,048,576 bytes. GT.M produces an error if
you specify a value greater than 1,048,576.
When a Unicode CHSET is in use, GT.M treats RECORDSIZE as a byte limit at
which to wrap or truncate output depending on [Z][NO]WRAP. For any Unicode
character set, GT.M ignores RECORDSIZE for a device which is already open
if any I/O has been done.
If the character set is not UTF-16, UTF-16LE, UTF-16BE, the default
RECORDSIZE is 32K-1bytes.
If the character set is UTF-16, UTF-16LE or UTF16-BE, the RECORDSIZE must
always be in multiples of 2. For these character sets, the default
RECORDIZE is 32K-4 bytes.
For all UTF-16 CHSET values, RECORDSIZE must be even and PAD characters
each occupy two bytes in the record.
5 REWIND
REWIND
REWIND Applies to: SD
REWIND Applies to: Sequential Files
REWIND positions the file pointer of a sequential disk.
By default, OPEN does not REWIND.
Example:
OPEN "test40.txt":(REWIND:RECORDSIZE=70:NOWRAP)
This example opens file test40.txt and places the file pointer at the
beginning of the file.
5 SEEK=strexpr
SEEK=strexpr
SEEK Applies to: SD
Positions the current file pointer to the location specified in strexpr.
The format of strexpr is a string of the form "[+|-]integer" where
unsigned value specifies an offset from the beginning of the file, and an
explicitly signed value specifies an offset relative to the current file
position. For STREAM or VARIABLE format, the positive intexpr after any
sign is a byte offset, while for a FIXED format, it is a record offset. In
order to deal with the possible presence of a Byte Order Marker (BOM),
SEEK for a FIXED format file written in a UTF character set must follow at
least one prior READ since the device was created.
**Note**
If an APPEND is combined with a SEEK deviceparameter the APPEND is done
first - regardless of deviceparameter order.
Example:
GTM>zprint ^seekdemo
seekdemo
new x,p
set p="seekfixed"
open p:(newversion:fixed:recordsize=60)
use p
; create file with 9 records of length 60 bytes each
; number from 0 to correspond to record offset
for i=0:1:8 write $justify(i_" - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-|",60)
use p:rewind
for i=0:1:8 read x set zk=$zkey use $p write "x= ",x," $zkey= ",zk,! use p
close p
write !!,"** OPEN with FIXED:RECORDSIZE=60:seek=""5""",!
open p:(fixed:recordsize=60:seek="5")
use p
read x set ZKEY=$zkey
;expect: $ZKEY= 6,0
use $p write "x= ",x," $zkey= ",ZKEY,!
write !,"** use with SEEK=""-3""",!
use p:seek="-3"
read x set ZKEY=$zkey
;expect: $ZKEY= 4,0
use $p write "x= ",x," $zkey= ",ZKEY,!
write !,"** use with SEEK=""-1"" to read from the same record. read x#20 to read a partial record",!
use p:seek="-1"
read x#20 set ZKEY=$zkey
;expect: $ZKEY= 3,20
use $p write "x= ",x," $zkey= ",ZKEY,!
write !,"** read x#40 to finish reading the record",!
use p
read x#40 set ZKEY=$zkey
;expect: $ZKEY= 4,0
use $p write "x= ",x," $zkey= ",ZKEY,!
write !,"** CLOSE NODESTROY and reOPEN with no deviceparameters",!
close p:nodestroy
open p
use p
read x set ZKEY=$zkey
;expect: $ZKEY= 5,0
use $p write "x= ",x," $zkey= ",ZKEY,!
write !,"** CLOSE NODESTROY and reOPEN with SEEK=""+2""",!
close p:nodestroy
open p:seek="+2"
use p
read x set ZKEY=$zkey
;expect: $ZKEY= 8,0
use $p write "x= ",x," $zkey= ",ZKEY,!
write !,"** CLOSE NODESTROY and reOPEN with M:SEEK=""+3""",!
close p:nodestroy
open p:(M:seek="+3")
use p
read x set ZKEY=$zkey
;expect: $ZKEY= 4,0
use $p write "x= ",x," $zkey= ",ZKEY,!
write !,"** CLOSE NODESTROY and reOPEN with APPEND:SEEK=""-1""",!
close p:nodestroy
open p:(append:seek="-1")
use p
read x set ZKEY=$zkey
;expect: $ZKEY= 9,0
use $p write "x= ",x," $zkey= ",ZKEY,!
close p
write !,"** CLOSE DESTROY and OPEN non-fixed with SEEK=""120"" and read 60 bytes",!
open p:seek="120"
use p
read x#60 set ZKEY=$zkey
;expect: $ZKEY= 180
use $p write "x= ",x," $zkey= ",ZKEY,!
write !,"** CLOSE NODESTROY and reOPEN with append:SEEK=""-60"" and read last 60 bytes",!
close p:nodestroy
open p:(append:seek="-60")
use p
read x#60 set ZKEY=$zkey
;expect: $ZKEY= 540
use $p write "x= ",x," $zkey= ",ZKEY,!
close p
quit
GTM>do ^seekdemo
x= 0 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 1,0
x= 1 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 2,0
x= 2 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 3,0
x= 3 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 4,0
x= 4 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 5,0
x= 5 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 6,0
x= 6 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 7,0
x= 7 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 8,0
x= 8 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 9,0
** OPEN with FIXED:RECORDSIZE=60:seek="5"
x= 5 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 6,0
** use with SEEK="-3"
x= 3 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 4,0
** use with SEEK="-1" to read from the same record. read x#20 to read a partial record
x= 3 - [-05-|-10-|-15-| $zkey= 3,20
** read x#40 to finish reading the record
x= -20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 4,0
** CLOSE NODESTROY and reOPEN with no deviceparameters
x= 4 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 5,0
** CLOSE NODESTROY and reOPEN with SEEK="+2"
x= 7 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 8,0
** CLOSE NODESTROY and reOPEN with M:SEEK="+3"
x= 3 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 4,0
** CLOSE NODESTROY and reOPEN with APPEND:SEEK="-1"
x= 8 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 9,0
** CLOSE DESTROY and OPEN non-fixed with SEEK="120" and read 60 bytes
x= 2 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 180
** CLOSE NODESTROY and reOPEN with append:SEEK="-60" and read last 60 bytes
x= 8 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 540
GTM>
This program demonstrates the use of the SEEK deviceparameter on OPEN and
USE and reOPEN after CLOSE NODESTROY. This test is shown as an M program
which may be executed, followed by the expected test output. First the
test creates the file called "seekfixed" with 9, 60-byte records and then
REWINDs and reads each record and outputs the record followed by $ZKEY
which is a record,byte pair. Note that the records are numbered from 0 to
match the SEEK record offset. Later in the test the same file is OPENed
VARIABLE so $ZKEY will be a byte offset in that case. Details are given
after the file output.
The first OPEN has deviceparameters set to (FIXED:RECORDSIZE=60:SEEK="5")
which SEEKs to record offset 5 or physical record 6. Note, FIXED length
records and RECORDSIZE remain in effect after a CLOSE NODESTROY unless
changed on a reOPEN. Record offset 5 is read and output along with $ZKEY=
6,0 which points to the beginning of record offset 6. Next, a USE with
SEEK="-3" is done to move back 3 records to read and output record
followed by $ZKEY= 4,0. A USE with SEEK="-1" moves back one record to the
beginning of the record just processed. A partial read of 20 bytes is done
to show a record offset 3 with a byte offset of 20 or $ZKEY= 3,20. A read
of 40 bytes is then done to finish processing that record for a $ZKEY=
4,0. Next a sequence of CLOSE NODESTROY and reOPENs are done. After the
first CLOSE NODESTROY a reOPEN is done with no deviceparameters. The state
of the file device, including file position, is restored and a read is
done of record offset 4 which is output followed by $ZKEY= 5,0. The file
device is then CLOSEd NODESTROY and a reOPEN is done with the only
deviceparameter being SEEK="+2". The state of the file device is restored
and a relative SEEK is done 2 records later in the file with a read which
outputs record offset 7 followed by $ZKEY= 8,0. The file device is then
CLOSEd NODESTORY and a reOPEN is done with deviceparameters (M:SEEK="+3").
The file device is OPENed at the beginning of the file due to the presence
of a deviceparameter (M) other than SEEK on reOPEN. A relative SEEK
forward of 3 records is then done from the beginning of the file and
record offset 3 is read and output followed by $ZKEY= 4,0. The file device
is then CLOSEd NODESTORY and a reOPEN is done with the (APPEND:SEEK="-1").
APPEND moves the file position to the EOF and then the SEEK="-1" moves the
file position to the beginning of record 8 - the final record in the file.
Note, the APPEND is applied prior to the SEEK - regardless of
deviceparameter order. The file device is then CLOSEd (DESTROY is the
default) and OPENed with the only deviceparameter being absolute
SEEK="120" to byte offset 120. This processing is NOFIXED by default and a
read of x#60 is done and output followed by $ZKEY= 180. The output is the
same as record 2 in FIXED format. Finally, the file device is then CLOSEd
NODESTROY and a reOPEN is done with deviceparameters (APPEND:SEEK="-60").
This will move the file position to the EOF and go back 60 bytes which is
the starting offset to the final record in the file. Another read of x#60
and is done and output followed by $ZKEY= 540 - which is the size of the
file.
5 SHELL
SHELL
SHELL Applies to: PIPE
The SHELL deviceparameter specifies the shell for the new process. By
default the newly created process uses the shell specified by the $SHELL
environment variable, otherwise, if the environment variable SHELL is
undefined the process uses /bin/sh.
5 STDERR
STDERR
STDERR Applies to: PIPE
The STDERR deviceparameter specifies that the stderr output from the
created process goes to a PIPE device with the name of the STDERR value.
This PIPE device acts as a restricted device that can appear only as the
argument to USE, READ and CLOSE commands. It is implicitly READONLY and an
attempt to WRITE to it triggers an error. If it has not previously acted
as the argument to an explicit CLOSE command, the CLOSE of the PIPE device
implicitly closes the the STDERR device.
5 STREAM
STREAM
[NO]STREAM Applies to: SD FIFO PIPE
STREAM and VARIABLE are semantically equivalent unless WRAP is disabled.
As long as records do not exceed the WIDTH, they are also equivalent.
When WRAP is disabled and a WRITE exceeds the WIDTH, both truncate the
line at the WIDTH, however in STREAM format, each WRITE argument truncates
after WIDTH characters regardless of whether the cursor exceeds the WIDTH,
while in VARIABLE format, no output ever exceeds the WIDTH.
While each WRITE argument is truncated if it exceeds the WIDTH, the total
record can be of arbitrary length. Note that, for efficiency, the compiler
combines sequential literal arguments of a single WRITE into a single
string so that the run-time system considers the combined length of the
sequence.
For STREAM or VARIABLE record format files, a READ returns when it
encounters an EOL, or has read #length characters for a READ #(fixed
length READ), or WIDTH characters if #length is not specified, whichever
occurs first.
By default, records are VARIABLE, NOSTREAM.
Example:
set sd="foo.txt"
open sd:(newversion:stream)
use sd:(width=20:nowrap)
for i=1:1:10 write " the quick brown fox jumped over the lazy dog ",$x,!
use sd:(rewind:width=100)
for i=1:1 use sd read x quit:$zeof use $principal write !,i,?5,x
close sd
quit
The output of this example is as follows:
1 the quick brown fox20
2 the quick brown fox20
3 the quick brown fox20
4 the quick brown fox20
5 the quick brown fox20
6 the quick brown fox20
7 the quick brown fox20
8 the quick brown fox20
9 the quick brown fox20
10 the quick brown fox20
If you change the FORMAT to VARIABLE, the same example produces the
following output.
1 the quick brown fox
2 the quick brown fox
3 the quick brown fox
4 the quick brown fox
5 the quick brown fox
6 the quick brown fox
7 the quick brown fox
8 the quick brown fox
9 the quick brown fox
10 the quick brown fox
If you remove the "!" format from the WRITE sequence for VARIABLE, the
same example produces the following output:
1 the quick brown fox
With STREAM, the same example produces the following output:
1 the quick brown fox20 the quick brown fox42 the quick brown fox64 the quick brown fox86 the quick b
2 rown fox108 the quick brown fox131 the quick brown fox154 the quick brown fox177 the quick brown fox
3 200 the quick brown fox223
With STREAM, changing the $X to "abc", the same example produces the
following output:
1 the quick brown fox the quick brown fox the quick brown fox the quick brown fox the quick brown fox
2 the quick brown fox the quick brown fox the quick brown fox the quick brown fox the quick brown fox
3
With STREAM, turning the comma between ".. lazy dog" and "abc" into a
separate WRITE statement produces:
1 the quick brown foxabc the quick brown foxabc the quick brown foxabc the quick brown foxabc the qui
2 ck brown foxabc the quick brown foxabc the quick brown foxabc the quick brown foxabc the quick brown
3 foxabc the quick brown foxabc
5 SYSTEM
SYSTEM
SYSTEM=expr Applies to: SOC(LOCAL) SD FIFO
This deviceparameter is a synonym for OWNER that is provided in the UNIX
version of GT.M for compatibility with OpenVMS applications.
Example:
GTM> set perm="rwx"
GTM>OPEN "test52.txt":(NEWVERSION:SYSTEM="r":GROUP=perm:WORLD=perm)
GTM>ZSYSTEM "ls -la test52.txt"
-r--rwxrwx 1 user group 0 Aug 20 18:36 test52.txt
GTM>
This example opens file test52.txt and sets read access for the owner,
while others have complete access.
5 TRUNCATE
TRUNCATE
[NO]TRUNCATE Applies to: SD
Truncates the file destroying all data beyond the current file pointer. If
APPEND is also specified, the file pointer will be positioned at the end
of the file even if TRUNCATE is before APPEND in the list of device
parameters.
TRUNCATE on a USE $PRINCIPAL command works on a stdout device when the
device supports the action.
5 UIC
UIC
UIC=expr Applies to: SOC(LOCAL) SD FIFO
Specifies the owner and group for the file.
Specifies the group that has access to the file. The format of the string
is "o,g" where g is a decimal number representing the group portion of the
UIC and o is a decimal number representing the owner portion. The
super-user can set the file UIC to any value. See the man page for the
chown() system call for the rules for regular users since they vary by
platform and system configuration.
5 VARIABLE
VARIABLE
VARIABLE Applies to: SD FIFO PIPE
Specifies the VARIABLE record length format for sequential disk files.
By default, records have variable length format.
5 WORLD
WORLD
WORLD=expr Applies to: SOC(LOCAL) SD FIFO
WORLD=expr Applies to: LOCAL Sockets, Sequential Files, and FIFO
Specifies access permissions for users other than the owner who are not in
the group specified for a file. This category of users is usually referred
to as other in UNIX. The expression is a character string evaluating to
null or to any combination of the letters RWX, indicating respectively
Read, Write, and eXecute access. When any one of these deviceparameters
appear on an OPEN of an existing file, any user category that is not
explicitly specified remains unchanged.
To modify file security, the user who issues the OPEN must have ownership.
By default, OPEN and CLOSE do not modify the permissions on an existing
file. Unless otherwise specified, when OPEN creates a new file, it
establishes security using standard defaulting rules.
Example:
OPEN "test51.txt":(NEWVERSION:WORLD="rw")
This example opens file test51.txt and specifies Read Write permission for
users not in owner's group.
5 WRITEONLY
WRITEONLY
[NO]WRITEONLY Applies to: PIPE
The WRITEONLY deviceparameter specifies that the PIPE acts only to send
its output to the created process. Any attempt to READ from such a PIPE
triggers an error. Note that when you open a PIPE with both STDERR and
WRITEONLY you can still READ from the STDERR device.
5 ZBFSIZE
ZBFSIZE
ZBFSIZE Applies to: SOC
Allocates a buffer used by GT.M when reading from a socket. The ZBFSIZE
deviceparameter should be at least as big as the largest message expected.
By default, the size of ZBFSIZE is 1024 and the maximum it can be is
1048576.
5 ZDELAY
ZDELAY
Z[NO]DELAY Applies to: SOC(TCP)
Controls buffering of data packets by the system TCP stack using the
TCP_NODELAY option to the setsockopt system call. This behavior is
sometimes known as the Nagle algorithm. The default is ZDELAY. This delays
sending additional packets until either an acknowledgment of previous
packets is received or an interval passes. If several packets are sent
from one end of a connection before the other end responds, setting
ZNODELAY may be desirable though at the cost of additional packets being
transmitted over the network. ZNODELAY must be fully spelled out.
LOCAL sockets ignore the ZDELAY deviceparameter.
Example:
open tcpdev:(LISTEN=portno_":TCP":attach="server":zbfsize=2048:zibfsize=1024):timeout:"SOCKET"
This example opens the socket device tcpdev and allocates a buffer size of
2048 bytes.
5 ZFF
ZFF
Z[NO]FF=expr Applied to: SOC
Z[NO]FF=expr Applies to: Socket Device
expr specifies a string of characters, typically in $CHAR() format to send
to socket device, whenever a routine issues a WRITE #. When no string is
specified or when ZFF="", then no characters are sent. The default in GT.M
is ZNOFF.
5 ZIBFSIZE
ZIBFSIZE
ZIBFSIZE Applies to: SOC(TCP)
ZIBFSIZE Applies to: Socket Device(TCP)
Allocates a buffer used by GT.M when reading from a socket. The ZBFSIZE
deviceparameter should be at least as big as the largest message expected.
By default, the size of ZBFSIZE is 1024 and the maximum it can be is
1048576.
Note that LOCAL sockets ignore the ZIBFSIZE deviceparameter.
4 OPEN_Deviceparameter_Table
OPEN Deviceparameter Table
+------------------------------------------------------------+
| OPEN Deviceparameters |
|------------------------------------------------------------|
| OPEN DEVICEPARAMETER | TRM | SD | FIFO | PIPE | NULL | SOC |
|------------------------------------------------------------|
| TRM: Valid for terminals and printers |
| |
| SD: Valid for sequential disk files |
| |
| FIFO: Valid for FIFOs |
| |
| NULL: Valid for null devices |
| |
| PIPE: Valid for PIPEs |
| |
| SOC: Valid for Socket devices |
|------------------------------------------------------------|
| APPEND | | X | | | | |
|----------------------+-----+----+------+------+------+-----|
| ATTACH=expr | | | | | | X |
|----------------------+-----+----+------+------+------+-----|
| CHSET=encoding | X | X | X | X | X | X |
|----------------------+-----+----+------+------+------+-----|
| COMMAND=expr | | | | X | | |
|----------------------+-----+----+------+------+------+-----|
| CONNECT=expr | | | | | | X |
|----------------------+-----+----+------+------+------+-----|
| [NO]DELIMITER | | | | | | X |
|----------------------+-----+----+------+------+------+-----|
| [NO]EMPT[ERM] | X | | | | | |
|----------------------+-----+----+------+------+------+-----|
| EXCEPTION=expr | X | X | X | | X | X |
|----------------------+-----+----+------+------+------+-----|
| FIFO | | | X | | | |
|----------------------+-----+----+------+------+------+-----|
| [NO]FIXED | | X | X | X | | |
|----------------------+-----+----+------+------+------+-----|
| [NO]FOLLOW | | X | | | | |
|----------------------+-----+----+------+------+------+-----|
| GROUP=expr | | X | X | | | |
|----------------------+-----+----+------+------+------+-----|
| KEY | | X | X | X | | |
|----------------------+-----+----+------+------+------+-----|
| IKEY | | X | X | X | | |
|----------------------+-----+----+------+------+------+-----|
| ICHSET=encoding | X | X | X | X | X | X |
|----------------------+-----+----+------+------+------+-----|
| INDEPENDENT | | | | X | | |
|----------------------+-----+----+------+------+------+-----|
| IOERROR=expr | | | | | | X |
|----------------------+-----+----+------+------+------+-----|
| [NO]NEWVERSION | | X | X | | | |
|----------------------+-----+----+------+------+------+-----|
| OCHSET=encoding | X | X | X | X | X | X |
|----------------------+-----+----+------+------+------+-----|
| OKEY | | X | X | X | | |
|----------------------+-----+----+------+------+------+-----|
| OWNER=expr | | X | X | | | |
|----------------------+-----+----+------+------+------+-----|
| PARSE | | | | X | | |
|----------------------+-----+----+------+------+------+-----|
| [NO]READONLY | | X | X | X | | |
|----------------------+-----+----+------+------+------+-----|
| RECORDSIZE=intexpr | | X | X | X | | |
|----------------------+-----+----+------+------+------+-----|
| SEEK=strexpr | | X | | | | |
|----------------------+-----+----+------+------+------+-----|
| SHELL=expr | | | | X | | |
|----------------------+-----+----+------+------+------+-----|
| STDERR=expr | | | | X | | |
|----------------------+-----+----+------+------+------+-----|
| [NO]STREAM | | X | | | | |
|----------------------+-----+----+------+------+------+-----|
| SYSTEM=expr | | X | X | | | |
|----------------------+-----+----+------+------+------+-----|
| [NO]TRUNCATE | | X | X | | | |
|----------------------+-----+----+------+------+------+-----|
| UIC=expr | | X | X | | | |
|----------------------+-----+----+------+------+------+-----|
| VARIABLE | | X | X | X | | |
|----------------------+-----+----+------+------+------+-----|
| WORLD=expr | | X | X | | | |
|----------------------+-----+----+------+------+------+-----|
| [NO]WRITEONLY | | | | X | | |
|----------------------+-----+----+------+------+------+-----|
| [Z][NO]WRAP | X | X | X | X | X | X |
|----------------------+-----+----+------+------+------+-----|
| ZBFSIZE | | | | | | X |
|----------------------+-----+----+------+------+------+-----|
| Z[NO]DELAY | | | | | | X |
|----------------------+-----+----+------+------+------+-----|
| Z[NO]FF | | | | | | X |
|----------------------+-----+----+------+------+------+-----|
| ZIBFSIZE | | | | | | X |
|----------------------+-----+----+------+------+------+-----|
| LISTEN=expr | | | | | | X |
+------------------------------------------------------------+
3 Use
Use
The USE command selects the current device for READs (input) and WRITEs
(output).
The format of the USE command is:
U[SE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
Example:
USE $P:(X=0:Y=$Y-1:NOECHO)
This example USEs the principal device. If that device is a terminal, the
deviceparameters turn off echo and position the cursor to the beginning of
the previous line.
4 USE_Deviceparameters
USE Deviceparameters
5 ATTACH
ATTACH
ATTACH=expr Applies to: Socket Device
expr specifies the handle for a socket in the socketpool. ATTACH looks up
expr in the socketpool's collection of sockets and brings the one found to
the current SOCKET device. If an ATTACH operation is successful, the
attached socket becomes the current socket for the device.
ATTACH is not compatible with any other device parameters in the USE
command.A socket can move from one device to another using DETACH/ATTACH.
**Note**
A socket does not carry I[O]CHSET with it while being moved. Such a socket
uses the I[O]CHSET of the device it is ATTACHed to. If there is input
still buffered, this may cause unintentional consequences in the
application if I[O]CHSET changes. GT.M does not detect (or report) a
change in I[O]CHSET due to DETACH/ATTACH.
5 CANONICAL
CANONICAL
[NO]CANONICAL Applies to: TRM
[NO]CANONICAL Applies to: Terminals and Printers
Enables or disables canonical input as controlled by the ICANON terminal
attribute. See the documentation on your platform for details, but in
general this would be erase and kill edit functions, and lines delimited
by NL (usually <LF>), EOF (usually ^D), and EOL (usually not defined).
By default, canonical input is enabled (that is [NO]CANONICAL is the
default).
5 CENABLE
CENABLE
[NO]CENABLE Applies to: Terminals and Printers
Enables or disables the ability to force GT.M into Direct Mode by entering
<CTRL-C> at $PRINCIPAL.
If CENABLE is set, <CTRL-C> interrupts process execution.
By default, CENABLE is set. If CTRAP contains $C(3), CENABLE is disabled.
Example:
use $principal:(nocenable:ctrap="":exception="")
5 CLEARSCREEN
CLEARSCREEN
CLEARSCREEN Applies to: TRM
CLEARSCREEN Applies to: Terminals and Printers
Clears the terminal screen from the present cursor position to the bottom
of the screen. The CLEARSCREEN deviceparameter does not change the cursor
position or the $X and $Y variables.
Example:
U $P:(X=0:Y=0:CLEAR)
This example positions the cursor to "home" in the upper left corner of a
VDT and clears the entire current screen "page."
5 CONNECT
CONNECT
CONNECT=expr Applies to: SOC
CONNECT=expr Applies to: Socket Device
Enables a client connection with a server, which is located by the
information provided by expr. A new socket is allocated for the client
connection and is made the current socket for the device, if the operation
is successful.
expr specifies the protocol and the protocol-specific information.
Currently, GT.M supports TCP/IP and LOCAL (also known as UNIX domain)
socket protocols.
For more information, refer to "CONNECT".
**Note**
CONNECT is not compatible with LISTEN.
Although CONNECT can be used with USE command, FIS recommends not to use
it that way, because unlike the OPEN command, there is no way to specify a
timeout to the USE command. CONNECT in the USE command take a default
timeout value of 0.
5 CONVERT
CONVERT
[NO]CONVERT Applies to: TRM
[NO]CONVERT Applies to: Terminals and Printers
Enables or disables GT.M from converting lowercase input to uppercase
during READs.
By default, the terminal device driver operates NOCONVERT.
Example:
use $principal:(convert)
READ X
This example converts all lowercase to uppercase during READ X.
5 CTRAP
CTRAP
CTRAP=expr Applies to: TRM
CTRAP=expr Applies to: Terminals and Printers
Establishes the <CTRL> characters in the expression as trap characters for
the current device. When GT.M receives a trap character in the input from
a device, GT.M issues a run-time exception. The device does not have to be
the current device, that is $IO.
The <CTRL> characters are ASCII 0 though 31.
For example, the command U $P:CTRAP=$C(26,30,7,19) sets a trap for the
ASCII characters <SUB>, <RS>, <BEL> and <DC3>.
Specifying CTRAP completely replaces the previous CTRAP list. Setting
CTRAP to the null string ("") disables character trapping.
A trap character enabled by CTRAP produces one of the following actions:
For more information on error handling, refer to Chapter 13: "Err
Processing".
When CTRAP includes <CTRL-C>, [NO]CENABLE has no effect. CTRAPping
<CTRL-C> also takes precedence over CENABLE.
5 DELIMITER
DELIMITER
[NO]DELIMITER Applies to: SOC
[NO]DELIMITER Applies to: Socket Device
DELIMITER establishes or replaces the list of delimiters used by the
current socket. The default is NODELIMITER.
expr must be a string of the following format:
1. ':' is used to separate delimiters (it is the delimiter for
delimiters).
2. '/' serves as an escape character.
**Note**
expr "ab:/:://:bc" is interpreted as four delimiters, which are "ab", ":",
"/", and "bc". One socket can have 0-64 delimiters and each delimiter can
contain 1-64 characters.
Example:
See "Socket (server.m)" example.
5 DETACH
DETACH
DETACH=expr Applies to: SOC
DETACH=expr Applies to: Socket Device
Removes the socket identified by expr from the current socket device,
without affecting any existing connection of that socket. The removed
socket is placed in the socketpool and may be attached to another socket
device. If the socket being removed is the current socket, then GT.M does
the following:
**Note**
A socket can move from one device to another using DETACH/ATTACH. A socket
does not carry I[O]CHSET with it while being moved. Such a socket uses the
I[O]CHSET of the device it is ATTACHed to. If there is input still
buffered, this may cause unintentional consequences in the application if
I[O]CHSET changes. GT.M does not detect (or report) a change in I[O]CHSET
due to DETACH/ATTACH.
Example:
GTM>set tcp="seerv" open tcp:(listen="6321:TCP":attach="serv")::"SOCKET"
GTM>zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
seerv OPEN SOCKET TOTAL=1 CURRENT=0
SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
GTM>set tcp="seerv" o tcp:(listen="6322:TCP":attach="serv2")::"SOCKET"
GTM>zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
seerv OPEN SOCKET TOTAL=2 CURRENT=1
SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
SOCKET[1]=serv2 DESC=4 LISTENING PASSIVE NOTRAP PORT=6322
ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
At this point, the socket device "seerv" has two sockets associated with
it.
The following command moves the "serv" socket to the "socketpool" device.
GTM>use tcp:detach="serv"
GTM>use 0 zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
seerv OPEN SOCKET TOTAL=1 CURRENT=0
SOCKET[0]=serv2 DESC=4 LISTENING PASSIVE NOTRAP PORT=6322
ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
socketpool OPEN SOCKET TOTAL=1 CURRENT=0
SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
Notice how socket "serv" is now associated with the pseudo socket device
"socketpool". Its only purpose is to hold detached sockets.
GTM>set tcp2="s2" o tcp2:::"SOCKET"
This creates a new socket device.
GTM>zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
s2 OPEN SOCKET TOTAL=0 CURRENT=0
seerv OPEN SOCKET TOTAL=1 CURRENT=0
SOCKET[0]=serv2 DESC=4 LISTENING PASSIVE NOTRAP PORT=6322
ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
socketpool OPEN SOCKET TOTAL=1 CURRENT=0
SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
The following command moves the serv socket from the socketpool to the
tcp2 device.
GTM>use tcp2:attach="serv"
GTM>use 0 zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
s2 OPEN SOCKET TOTAL=1 CURRENT=0
SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
seerv OPEN SOCKET TOTAL=1 CURRENT=0
SOCKET[0]=serv2 DESC=4 LISTENING PASSIVE NOTRAP PORT=6322
ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
socketpool OPEN SOCKET TOTAL=0 CURRENT=-1
5 DOWNSCROLL
DOWNSCROLL
DOWNSCROLL Applies to: TRM
DOWNSCROLL Applies to: Terminals and Printers
If $Y=0, DOWNSCROLL does nothing. Otherwise, DOWNSCROLL moves the cursor
up one line on the terminal screen and decrements $Y by one. DOWNSCROLL
does not change the column position or $X. Some terminal hardware may not
support DOWNSCROLL.
5 ECHO
ECHO
[NO]ECHO Applies to: TRM
[NO]ECHO Applies to: Terminals and Printers
Enables or disables the echo of terminal input. If you disable ECHO, the
EDITING functions will be disabled and any input is not available for
later recall.
By default, terminal input ECHOes.
Example:
use $principal:noecho
This example disables the echo of terminal input.
5 EDITING
EDITING
[NO]EDITING Applies to: TRM
Enables the EDITING mode for the $PRINCIPAL device. If you enable EDITING,
GT.M allows the use of the left and right cursor movement keys and certain
<CTRL> characters within the current input line. You can recall the last
input line using the up or down arrow key. The editing functions are the
same as during direct mode command input as described in the "Line
Editing" section of the "Operating & Debugging in Direct Mode" chapter
except that backspace is not treated the same as the erase character from
terminfo which is usually delete (ASCII 127). NOECHO disables EDITING
mode.
Set the environment variable gtm_principal_editing to specify the mode for
EDITING. For example, gtm_principal_editing="EDITING" enables EDITING mode
at GT.M startup. You can also specify the mode for INSERT. For example,
gtm_principal_editing="NOINSERT:EDITING". If you specify both modes then
separate them with a colon (":") and put them in any order.
By default, EDITING mode is disabled.
If you enable the EDITING mode, escape sequences do not terminate READs.
Enabling PASTHRU mode supersedes EDITING mode.
If any of the EDITING <CTRL> characters are in the CTRAP list, their
editing functions are not available since CTRAP takes precedence. However
the EDITING <CTRL> characters takes precedence over the TERMINATOR list.
**Note**
M READ EDITING depends on the values of $X and $Y being correct. If the
application sends its own escape sequences or control characters, which
change the cursor position, it must properly update $X and $Y before doing
a M READ with EDITING enabled to ensure correct formatting during input.
5 EMPTERM
EMPTERM
[NO]EMPT[ERM] Applies to: TRM
Allows an "Erase" character on an empty input line to terminate a READ or
READ # command. The default is NOEMPTERM. The gtm_principal_editing
environment variable specifies the initial setting of [NO]EMPTERM. The
TERMINFO specified by the current value of the TERM environment variable
defines capnames values "kbs" and/or "kdch1" with character sequences for
"Erase." If "kbs" or "kdch1" are multi-character values, you must also
specify the ESCAPE or EDIT deviceparameters for EMPTERM recognition.
The erase character as set and shown by stty also terminates a READ
command with an empty input line. You can set this erase character to
various values using the stty shell command. Typical values of an erase
character are <CTRL-H> and <CTRL-?>. Characters set and shown with stty
setting must match what the terminal emulator sends.
The environment variable TERM must specify a terminfo entry that matches
both what the terminal (or terminal emulator) sends and expects.
5 ERASELINE
ERASELINE
ERASELINE Applies to: TRM
ERASELINE Applies to: Terminals and Printers
Clears the current line from the physical cursor position to the end of
the line. ERASELINE does not affect the physical cursor position, or $X
and $Y.
5 ESCAPE
ESCAPE
[NO]ESCAPE Applies to: TRM
[NO]ESCAPE Applies to: Terminals and Printers
Enables or disables GT.M processing of escape sequences.
The following events result when a terminal has ESCAPE sequence processing
enabled. When an <ESC> or <CSI> arrives in the terminal input, the device
driver verifies the sequence that follows as a valid ANSI escape sequence,
terminates the READ, and sets $ZB to contain the entire escape sequence.
In the case of a READ * when ESCAPE sequence processing is enabled and an
escape introducer is read, the entire escape sequence is returned in $ZB
and the ASCII representation of the first character is returned in the
argument of the READ *.
When escape processing is disabled, READ *x returns 27 in x for an <ESC>.
If the escape introducer is also a TERMINATOR, $ZB has a string of length
one (1), and a value of the $ASCII() representation of the escape
introducer; otherwise, $ZB holds the empty string. For single character
and short fixed reads with NOESCAPE, the remaining characters in the
escape sequence will be in the input stream for subsequent READS
regardless of [NO]TYPEAHEAD.
An application that operates with (NOESCAPE:TERM=$C(13)) must provide
successive READ * commands to remove the remaining characters in the
escape sequence from the input stream.
By default, ESCAPE processing is disabled.
Example:
use $principal:(noescape:term=$c(13))
This example disables the escape sequence processing and set $c(13) as the
line terminator.
5 EXCEPTION
EXCEPTION
EXCEPTION=expr Applies to: All devices
EXCEPTION=expr Applies to: All devices
Defines an error handler for an I/O device. The expression must contain a
fragment of GT.M code (for example, GOTO ERRFILE) that GT.M XECUTEs when
the driver for the device detects an error, or an entryref to which GT.M
transfers control, as appropriate for the current gtm_ztrap_form.
5 FILTER
FILTER
[NO]FILTER[=expr] Applies to: TRM SOC NULL
[NO]FILTER[=expr] Applies to: Terminals and Printers, Socket Device, and
NULL Device
Specifies character filtering for specified cursor movement sequences.
Filtering requires character by character examination of all output and
reduces I/O performance.
Each FILTER deviceparameter can have only one argument. However, multiple
FILTER deviceparameters can appear in a single USE command, each with
different arguments.
By default, GT.M does not perform output filtering. For GT.M to maintain
$X for non-graphic characters as described by the standard,
FILTER="CHARACTERS" must be enabled. Output filtering adds additional
overhead to I/O processing.
Example:
use tcpdev:filter="NOESCAPE"
This example removes the effect of escape sequences on the maintenance $X
and $Y.
5 FOLLOW
FOLLOW
[NO]FOLLOW Applies to: SD
Configures READ to return only when it has a complete record or reaches
any specified timeout; it waits for more input rather than terminating on
an EOF (end-of-file) condition.
The USE command can switch a device from NOFOLLOW to FOLLOW or from FOLLOW
to NOFOLLOW. This provides a READ mode of operation similar to a tail -f
in UNIX.
5 HOSTSYNC
HOSTSYNC
[NO]HOSTSYNC Applies to: TRM
[NO]HOSTSYNC Applies to: Terminals and Printers
Enables or disables the use of XON/XOFF by the host to throttle input and
prevent impending buffer overruns for a terminal. This deviceparameter
provides a control mechanism for the host over asynchronous communication
lines to help prevent data loss when hardware is slow and/or processing
load is high.
By default, HOSTSYNC is disabled.
5 KEY
KEY
Applies to: SD, PIPE, and FIFO
Specifies information about the key file to use for reading and writing
encrypted data. The syntax of the KEY deviceparameter is as follows:
KEY="key_name [IV]"
key_name is case-sensitive and must match a key name in the "files"
section of the gtmcrypt_config file. The optional IV specifies an
initialization vector to use for encryption and decryption.
For more information and an example, refer to the description of KEY
deviceparameter of OPEN.
5 IKEY
IKEY
Applies to: SD, PIPE, and FIFO
IKEY allows the use of a seperate key to READ from a device; for example,
when a GT.M process is an element of a UNIX pipe. The format of the IKEY
deviceparameter is:
IKEY="key_name [IV]"
key_name is case-sensitive and must match a key name in the "files"
section of the gtmcrypt_config file. The optional IV specifies an
initialization vector to use for encryption and decryption.
For more information, refer to the description of KEY deviceparameter of
OPEN.
5 INREWIND
INREWIND
Applies to: SD
Performs a REWIND on input when $PRINCIPAL identifies a device that
supports REWIND. Use this deviceparameter with $PRINCIPAL when redirected
from a file.
5 INSEEK=strexpr
INSEEK=strexpr
Applies to: SD
Performs a SEEK on input when $PRINCIPAL identifies a device that supports
SEEK. Use this deviceparameter with $PRINCIPAL when redirected from a
file.
5 IOERROR
IOERROR
IOERROR=expr Applies to: SOC
IOERROR=expr Applies to: Socket Device
Enables exception handling in socket devices. expr specifies the I/O error
trapping mode. A value equal to "TRAP" specifies that I/O errors on a
device raise error conditions. A value equal to "NOTRAP", or when IOERROR
is not specified, indicates that an I/O error on a device does not raise
error conditions.
**Note**
GT.M currently handles exception handling at device level instead of
socket level.
Example:
use sock:(ioerror="TRAP":exception="zgoto "_$zlevel_":error")
This example enables exception handling in socket device sock and
specifies that all I/O errors on sock raise the error condition.
5 LENGTH
LENGTH
[Z]LENGTH=intexpr Applies to: TRM SOC SD FIFO PIPE NULL
[Z]LENGTH=intexpr Applies to: Terminals and Printers, Socket Device, and
NULL Device.
Sets the virtual page length for an I/O device to the integer expression.
You can specify the virtual page length up to 1,048,576. The page length
controls the point at which the device driver automatically resets $Y to
0.
By default, for terminals, GT.M uses the terminfo variable lines (which
may be from the terminal definition or from a stty command) as the initial
value for LENGTH. The default length for null device and socket device is
66.
Setting LENGTH to zero prevents resetting $Y to zero.
Example:
use sock:(zwidth=80:znoff:zlength=24)
This example sets the virtual page length to 24 for socket device sock.
5 LISTEN
LISTEN
LISTEN=expr Applies to: SOC
A new socket is allocated to listen for a connection. It is made the
current socket for the device, if the operation is successful.
expr specifies the protocol and the protocol-specific information.
Currently, GT.M supports TCP/IP and LOCAL (also known as UNIX domain)
socket protocols.
Example:
GTM>set tcp="seerv" open tcp:(listen="6321:TCP":attach="serv")::"SOCKET"
GTM>use tcp:listen="6322:TCP"
GTM>use 0 zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
seerv OPEN SOCKET TOTAL=2 CURRENT=1
SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
SOCKET[1]=h12185825450 DESC=4 LISTENING PASSIVE NOTRAP PORT=6322
ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
5 OKEY
OKEY
Applies to: SD, PIPE, and FIFO
OKEY allows the use of a seperate key for WRITE to a device; for example,
when a GT.M process is an element of a UNIX pipe. The format of the IKEY
deviceparameter is:
OKEY="key_name [IV]"
key_name is case-sensitive and must match a key name in the "files"
section of the gtmcrypt_config file. The optional IV specifies an
initialization vector to use for encryption and decryption.
For more information, refer to the description of KEY deviceparameter of
OPEN.
5 OUTREWIND
OUTREWIND
Applies to: SD
Performs a REWIND on output when $PRINCIPAL identifies a device that
supports REWIND. Use this deviceparameter with $PRINCIPAL when redirected
to a file.
5 OUTSEEK=strexpr
OUTSEEK=strexpr
Applies to: SD
Performs a SEEK on output when $PRINCIPAL identifies a device that
supports SEEK. Use this deviceparameter with $PRINCIPAL when redirected to
a file.
5 PASTHRU
PASTHRU
[NO]PASTHRU Applies to: TRM
[NO]PASTHRU Applies to: Terminals and Printers
Enables or disables interpretation of the ERASE character for a terminal.
PASTHRU shifts management of handling and response to ERASE characters in
the input stream from GT.M to the application code.
Exercise caution with PASTHRU in debugging, because using a PASTHRU
terminal in Direct Mode is somewhat awkward.
[NO]TTSYNC must be used with [NO]PASTHRU to control XON/XOFF handling.
By default, the device driver operates NOPASTHRU.
PASTHRU supersedes line editing.
5 READSYNC
READSYNC
[NO]READSYNC Applies to: TRM
Enables or disables automatic output of <XON> before a READ and <XOFF>
after a READ.
By default, the terminal drivers operate NOREADSYNC.
5 REWIND
REWIND
REWIND Applies to: SD
REWIND places the file pointer to the beginning of the file.
By default, USE does not REWIND.
REWIND on redirected output for $PRINCIPAL is the same as OUTREWIND.
5 SEEK=strexpr
SEEK=strexpr
SEEK Applies to: SD
Positions the current file pointer to the location specified in strexpr.
The format of strexpr is a string of the form "[+|-]integer" where an
unsigned value specifies an offset from the beginning of the file, and an
explicitly signed value specifies an offset relative to the current file
position. For STREAM or VARIABLE format, the positive intexpr after any
sign is a byte offset, while for a FIXED format, it is a record offset. In
order to deal with the possible presence of a Byte Order Marker (BOM),
SEEK for a FIXED format file written in a UTF character set must follow at
least one prior READ since the device was created.
SEEK on redirected input for $PRINCIPAL is the same as INSEEK.
5 SOCKET
SOCKET
SOCKET=expr Applies to: SOC
Makes the socket specified by the handle named in expr the current socket
for the Socket device . If the named socket is a listening socket, it
checks for an incoming connection request and if one is available, it
accepts the request and creates a new connected socket in which case $KEY
provides information on the new socket Specifying a socket handle not
contained in the Socket device generates an error.
**Note**
SOCKET is compatible with DELIMITER only.
5 TERMINATOR
TERMINATOR
[NO]TERMINATOR[=expr] Applies to: TRM
Specifies which of the 256 ASCII characters terminate a READ. For example,
TERMINATOR=$C(0) makes <NUL> the terminator.
When NOESCAPE is in effect, TERMINATOR controls whether or not <ESC> or
<CSI> are treated as terminators, however, when ESCAPE processing is
enabled, the entire escape sequence is treated as a terminator regardless
of the TERMINATOR specification.
When EDITING is enabled, the control characters used for editing are not
treated as terminators even if they are in the TERMINATOR list.
You can define any control character as a terminator, but they are all
single character.
When the terminal is in UTF-8 mode (chset=utf8,) GT.M limits the
terminator characters to the first 127 which are common between ASCII and
Unicode. In M mode, any of the 256 characters may be specified a
terminator.
In UTF-8 mode, if CR is in the terminator list (either by default or
explicitly,) GT.M ignore the following LF to keep with the standard
Unicode line terminator scheme.
NOTERMINATOR eliminates all terminators. When a terminal has all
terminators disabled, fixed length READ and READ * terminate on receipt of
some number of characters, and a timed READ terminates on timeout, but any
other READ only terminates when the input fills the terminal read buffer.
By default, terminals recognize <CR>, <LF>, and <ESC> as terminators (that
is, TERMINATOR=$C(10, 13,27)). TERMINATOR="" restores the default. In
UTF-8 mode, the usual Unicode line terminators are also included in the
default set of terminators.
Example:
GTM> USE $P:TERM=$C(26,13,11,7)
This example enables the ASCII characters <SUB>, <CR>, <VT> and <BEL> as
READ terminators.
5 TRUNCATE
TRUNCATE
[NO]TRUNCATE Applies to: SD
Enables or disables overwriting of existing data in sequential files.
Because the position of each record depends on the prior record, a WRITE
destroys the ability to reliably position to subsequent records in a file.
Therefore, by default (NOTRUNCATE), GT.M permits WRITEs only when the file
pointer is positioned at the end-of-file. When a device has TRUNCATE
enabled, a WRITE issued when the file pointer is not at end-of-file
truncates the file by destroying all data from the file pointer to the
end-of-file.
By default, OPEN accesses files NOTRUNCATE, which does not allow
overwriting of sequential files.
This deviceparameter may not be supported by your platform.
5 TTSYNC
TTSYNC
[NO]TTSYNC Applies to: TRM
Enables or disables recognition of XON/XOFF for terminal output.
**Note**
A terminal may have its own handling of XON/XOFF, controlled by a set-up
mode or by switches. If an application requires program recognition of
<CTRL-S> and <CTRL-Q>, the terminals may require reconfiguration.
5 TYPEAHEAD
TYPEAHEAD
[NO]TYPEAHEAD Applies to: TRM
[NO]TYPEAHEAD Applies to: Terminals and Printers
Enables or disables type-ahead buffering for a terminal. When TYPEAHEAD is
disabled, any pending input which has not yet been read will be discarded
before input is read for each READ argument. When TYPEAHEAD is enabled,
any input not read by one READ argument will remain available for the next
READ argument or command.
The size of the type-ahead buffer limits the amount of data entered at the
terminal that the device driver can store in anticipation of future READs.
By default, the terminal device driver accepts TYPEAHEAD.
5 UPSCROLL
UPSCROLL
UPSCROLL Applies to: TRM
Moves the cursor down one line on the terminal screen. If $Y=LENGTH-1,
UPSCROLL sets $Y=0. Otherwise UPSCROLL increments $Y by one. If the cursor
is physically at the bottom of the page, the screen scrolls up one line.
UPSCROLL does not change the column position or $X.
5 WIDTH
WIDTH
[Z]WIDTH=intexpr Applies to: TRM SOC NULL SD FIFO PIPE
[Z]WIDTH=intexpr Applies to: Terminals and Printers, Socket Device, NULL
Device, PIPE, and Sequential Files
Sets the device's logical record size and enables WRAP. The default WIDTH
for SD and FIFO is taken from the RECORDSIZE.
NOWRAP and WIDTH supersede each other. When WIDTH and NOWRAP appear
together on the same USE command, the final one controls the device
behavior. For a terminal, WIDTH=0 is equivalent to WIDTH=n:NOWRAP, where n
is the default length of a logical record on that terminal.
Terminals inherit their default WIDTH in GT.M from the invoking shell
environment. The default WIDTH for null and socket device is 255.
For SD and SOC which support 1MB strings, you can specify WIDTH up to
1,048,576.
For non fixed format, always include the line terminator in WIDTH
otherwise you get NULL reads after records which are WIDTH wide.
In UTF-8 mode and TRM, SD, and FIFO output, the WIDTH deviceparameter is
in units of display-columns and is used with $X to control truncation and
WRAPing for output and maintenance of $X and $Y for input.
In UTF-8 mode and SOC, the WIDTH deviceparameter is in units of Unicode
code points and is used with $X to control truncation and wrapping for
output and maintenance of $X and $Y for input.
In M mode if WIDTH is set to 0, GT.M uses the default WIDTH of the TRM and
SOC devices. USE x:WIDTH=0 is equivalent to USE
x:(WIDTH=<device-default>:NOWRAP. For SD and FIFO devices in M mode, the
device default is the RECORDSIZE.
GT.M format control characters, FILTER, and the device WIDTH and WRAP also
have an effect on $X.
In UTF-8 mode and SOC output, the WIDTH deviceparameter specifies the
number of characters in Unicode.
5 WRAP
WRAP
[Z][NO]WRAP Applies to: TRM SOC NULL SD FIFO
[Z][NO]WRAP Applies to: Terminals and Printers, FIFO, Socket Device, NULL
Device, and Sequential Files
Enables or disables automatic record termination. When the current record
size ($X) reaches the maximum WIDTH and the device has WRAP enabled, GT.M
starts a new record, as if the routine had issued a WRITE ! command.
NOWRAP causes GT.M to require a WRITE ! to terminate the record. NOWRAP
allows $X to become greater than the device WIDTH for terminals.
By default, WIDTH sets WRAP. When WIDTH and NOWRAP appear together on the
same USE command, the last one controls the device behavior.
By default, records WRAP.
Example:
See WRAP examples in the OPEN deviceparameters section.
5 X
X
X=intexpr Applies to: TRM
X=intexpr Applies to: Terminals and Printers
$X positions the cursor to a vertical column on the terminal. If NOWRAP is
enabled or intexpr<WIDTH, GT.M sets $X=intexpr. If WRAP is enabled and
intexpr>WIDTH, GT.M sets $X=intexpr#WIDTH, where # is the GT.M modulo
operator. The resulting $X determines the actual physical position.
To ensure that $Y and $X match what is occurring visually on the terminal,
the GT.M deviceparameters and the device characteristics must match at all
times.
The terminal hardware may affect physical cursor positioning. The X
deviceparameter does not change the cursor row or update $Y.
5 Y
Y
Y=intexpr Applies to: TRM
Y=intexpr Applies to: Terminals and Printers
Positions the cursor to a horizontal row on the terminal.
GT.M sets $Y=intexpr#LENGTH, where # is the GT.M modulo operator. If
intexpr<LENGTH, the resulting $Y determines the physical position. If
intexpr>LENGTH, the cursor is positioned so that $Y=intexpr#LENGTH, where
# is the GT.M module operator. The terminal hardware may affect physical
cursor positioning.
To ensure that $Y and $X match what is occurring visually on the terminal,
the GT.M deviceparameters and the device characteristics must match at all
times. For example, if a process initiates a subprocess that changes the
terminal wrap setting from NOWRAP, previously set with the GT.M USE
command to WRAP , GT.M does not reflect the change when the subprocess
completes. Therefore, wraps on the terminal do not reflect in the values
of $X and $Y.
The Y deviceparameter does not change the cursor column or update $X.
5 ZBFSIZE
ZBFSIZE
ZBFSIZE Applies to: SOC
ZBFSIZE Applies to: Socket Device
Allocates a buffer used by GT.M when reading from a socket. The ZBFSIZE
deviceparameter should be at least as big as the largest message expected.
By default, the size of ZBFSIZE is 1024 and the maximum it can be is
1048576.
5 ZDELAY
ZDELAY
Z[NO]DELAY Applies to: SOC
Z[NO]DELAY Applies to: Socket Device
Controls buffering of data packets by the system TCP stack using the
TCP_NODELAY option to the SETSOCKOPT system call. This behavior is
sometimes known as the Nagle algorithm. The default is ZDELAY. This delays
sending additional packets until either an acknowledgement of previous
packets is received or an interval passes. If several packets are sent
from one end of a connection before the other end responds, setting
ZNODELAY may be desirable though at the cost of additional packets being
transmitted over the network. ZNODELAY must be fully spelled out.
5 ZFF
ZFF
Z[NO]FF=expr Applies to: SOC
Z[NO]FF=expr Applies to: Socket Device
expr specifies a string of characters, typically in $CHAR() format to send
to socket device, whenever a routine issues a WRITE #. When no string is
specified or when ZFF="", then no characters are sent. The default in GT.M
is ZNOFF.
Example:
u tcpdev:(zwidth=80:zff=$char(13):zlength=24)
This example sends $char(13) to the current socket of device tcpdev on
every WRITE #.
5 ZIBFSIZE
ZIBFSIZE
ZIBFSIZE Applies to: SOC
ZIBFSIZE Applies to: Socket Device
Sets the buffer size used by the network software (setsockopt SO_RCVBUF).
The default and the maximum values depend on the platform and/or system
parameters.
4 Summary
Summary
+-----------------------------------------------------------+
| USE Deviceparameters |
|-----------------------------------------------------------|
| USE DEVICEPARAMETER | TRM | SD | FIFO | PIPE | NULL | SOC |
|-----------------------------------------------------------|
| TRM: Valid for terminals and printers |
| |
| SD: Valid for sequential files |
| |
| FIFO: Valid for FIFOs |
| |
| PIPE: Valid for PIPE devices |
| |
| NULL: Valid for null devices |
| |
| SOC: Valid for socket devices |
|-----------------------------------------------------------|
| ATTACH | | | | | | X |
|---------------------+-----+----+------+------+------+-----|
| CANONICAL | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]CENABLE | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| CLEARSCREEN | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| CONNECT | | | | | | X |
|---------------------+-----+----+------+------+------+-----|
| [NO]CONVERT | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| CTRAP=expr | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]DELIMITER | | | | | | X |
|---------------------+-----+----+------+------+------+-----|
| DETACH=expr | | | | | | X |
|---------------------+-----+----+------+------+------+-----|
| DOWNSCROLL | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]EBCDIC | | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]ECHO | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]EMPT[ERM] | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| ERASELINE | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| ERASETAPE | | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]ESCAPE | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| EXCEPTION=expr | X | X | X | | X | X |
|---------------------+-----+----+------+------+------+-----|
| [NO]FILTER[=expr] | X | | | | X | X |
|---------------------+-----+----+------+------+------+-----|
| FLUSH | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]FOLLOW | | X | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]HOSTSYNC | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| KEY | | X | X | X | | |
|---------------------+-----+----+------+------+------+-----|
| IKEY | | X | X | X | | |
|---------------------+-----+----+------+------+------+-----|
| IOERROR | | | | | | X |
|---------------------+-----+----+------+------+------+-----|
| INREWIND | | X | | | | |
|---------------------+-----+----+------+------+------+-----|
| INSEEK | | X | | | | |
|---------------------+-----+----+------+------+------+-----|
| [Z]LENGTH=expr | X | X | X | | X | X |
|---------------------+-----+----+------+------+------+-----|
| OKEY | | X | X | X | | |
|---------------------+-----+----+------+------+------+-----|
| OUTREWIND | | X | | | | |
|---------------------+-----+----+------+------+------+-----|
| OUTSEEK | | X | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]PASTHRU | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]RCHK | | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]RETRY | | | | | | |
|---------------------+-----+----+------+------+------+-----|
| REWIND | | X | | | | |
|---------------------+-----+----+------+------+------+-----|
| SEEK=strexpr | | X | | | | |
|---------------------+-----+----+------+------+------+-----|
| SKIPFILE=intexpr | | | | | | |
|---------------------+-----+----+------+------+------+-----|
| SOCKET | | | | | | X |
|---------------------+-----+----+------+------+------+-----|
| SPACE=intexpr | | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]STREAM | | X | | | | |
|---------------------+-----+----+------+------+------+-----|
| TERMINATOR[=expr] | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]TRUNCATE | | X | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]TYPEAHEAD | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| UPSCROLL | X | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [NO]WCHK | | | | | | |
|---------------------+-----+----+------+------+------+-----|
| [Z]WIDTH=intexpr | X | X | X | X | X | X |
|---------------------+-----+----+------+------+------+-----|
| [Z][NO]WRAP | X | X | X | | X | X |
|---------------------+-----+----+------+------+------+-----|
| WRITELB=expr | | | | | | |
|---------------------+-----+----+------+------+------+-----|
| WRITETM | | | | | | |
|---------------------+-----+----+------+------+------+-----|
| X=intexpr | X | | | | X | |
|---------------------+-----+----+------+------+------+-----|
| Y=intexpr | X | | | | X | |
|---------------------+-----+----+------+------+------+-----|
| ZBFSIZE | | | | | | X |
|---------------------+-----+----+------+------+------+-----|
| Z[NO]DELAY | | | | | | X |
|---------------------+-----+----+------+------+------+-----|
| Z[NO]FF | | | | | | X |
|---------------------+-----+----+------+------+------+-----|
| ZIBUFSIZE | | | | | | X |
|---------------------+-----+----+------+------+------+-----|
| LISTEN | | | | | | X |
+-----------------------------------------------------------+
3 Close
Close
The CLOSE command breaks the connection between a process and a device.
The format of the CLOSE command is:
C[LOSE][:tvexpr] expr[:(keyword[=expr][:...])][,...]
When a CLOSE is issued, GT.M flushes all pending output to the device, and
processes any deviceparameters. CLOSEing a device not currently OPEN has
no effect.
If a partial record has been output, a WRITE ! is done to complete it. To
suppress this action, set $X to zero before the CLOSE.
GT.M retains the characteristics of all device types, except a sequential
file, for use in case of subsequent re-OPENs. If the device is a
sequential file, characteristics controlled by deviceparameters are lost
after the CLOSE.
If the device being CLOSEd is $IO, GT.M implicitly USEs $PRINCIPAL. GT.M
ignores CLOSE $PRINCIPAL.
Example:
CLOSE SD:RENAME=SD_".SAV"
This closes the device and, if it is a disk file, renames it to have the
type .SAV.
Example:
CLOSE SOCKDEV:(SOCKET="LOCALSOCK1":DELETE)
This deletes the socket file associated with LOCALSOCK1 if it is a
listening socket and closes only the named socket on the socket device.
4 CLOSE_Deviceparameters_Table
CLOSE Deviceparameters Table
+-----------------------------------------------+
| CLOSE Deviceparameters |
|-----------------------------------------------|
| CLOSE DEVICEPARAMETER | TRM | SD | FIFO | SOC |
|-----------------------------------------------|
| SD: Valid for sequential disk files |
| |
| TRM: Valid for terminals and printers |
| |
| FIFO: Valid for FIFOs |
| |
| NULL: Valid for NULL devices |
| |
| SOC: Valid for Socket devices |
|-----------------------------------------------|
| DELETE | | X | X | |
|-----------------------+-----+----+------+-----|
| DESTROY | | X | X | X |
|-----------------------+-----+----+------+-----|
| ERASETAPE=expr | | | | |
|-----------------------+-----+----+------+-----|
| EXCEPTION=expr | X | X | X | X |
|-----------------------+-----+----+------+-----|
| GROUP=expr | | X | | |
|-----------------------+-----+----+------+-----|
| OWNER=expr | | X | | |
|-----------------------+-----+----+------+-----|
| RENAME=expr | | X | | |
|-----------------------+-----+----+------+-----|
| REWIND | | | | |
|-----------------------+-----+----+------+-----|
| SOCKET | | | | X |
|-----------------------+-----+----+------+-----|
| SPACE | | | | |
|-----------------------+-----+----+------+-----|
| SYSTEM=expr | | X | | |
|-----------------------+-----+----+------+-----|
| UIC=group name | | X | | |
|-----------------------+-----+----+------+-----|
| WORLD=expr | | X | | |
+-----------------------------------------------+
**Note**
Since EXCEPTION is the only CLOSE deviceparameter that applies to NULL,
the NULL device column is not shown in the table above.
3 Deviceparameter_Summary
Deviceparameter Summary
+-----------------------------------------+
| Deviceparameter Summary |
|-----------------------------------------|
| DEVICEPARAMETER | OPEN | USE | CLOSE |
|--------------------+------+-----+-------|
| APPEND | X | | |
|--------------------+------+-----+-------|
| ATTACH | | X | |
|--------------------+------+-----+-------|
| BLOCKSIZE=intexpr | X | | |
|--------------------+------+-----+-------|
| [NO]CENABLE | | X | |
|--------------------+------+-----+-------|
| CLEARSCREEN | | X | |
|--------------------+------+-----+-------|
| CONNECT | X | X | |
|--------------------+------+-----+-------|
| [NO]CONVERT | | X | |
|--------------------+------+-----+-------|
| CTRAP | | X | |
|--------------------+------+-----+-------|
| DELETE | | | X |
|--------------------+------+-----+-------|
| [NO]DELIMITER | X | X | |
|--------------------+------+-----+-------|
| DETACH | | X | |
|--------------------+------+-----+-------|
| DOWNSCROLL | | X | |
|--------------------+------+-----+-------|
| [NO]ECHO | | X | |
|--------------------+------+-----+-------|
| ERASELINE | | X | |
|--------------------+------+-----+-------|
| [NO]ESCAPE | | X | |
|--------------------+------+-----+-------|
| EXCEPTION=expr | X | X | X |
|--------------------+------+-----+-------|
| [NO]FILTER[=expr] | | X | |
|--------------------+------+-----+-------|
| [NO]FIXED | X | | |
|--------------------+------+-----+-------|
| FLUSH | | X | |
|--------------------+------+-----+-------|
| GROUP=expr | X | X | X |
|--------------------+------+-----+-------|
| KEY | X | X | |
|--------------------+------+-----+-------|
| IKEY | X | X | |
|--------------------+------+-----+-------|
| IOERROR=expr | X | X | |
|--------------------+------+-----+-------|
| [NO]HOSTSYNC | | X | |
|--------------------+------+-----+-------|
| [Z]LENGTH=intexpr | | X | |
|--------------------+------+-----+-------|
| NEWVERSION | X | | |
|--------------------+------+-----+-------|
| OKEY | X | X | |
|--------------------+------+-----+-------|
| OWNER=expr | X | X | X |
|--------------------+------+-----+-------|
| [NO]PASTHRU | | X | |
|--------------------+------+-----+-------|
| [NO]RCHK | X | X | |
|--------------------+------+-----+-------|
| [NO]READONLY | X | | |
|--------------------+------+-----+-------|
| RECORDSIZE=intexpr | X | | |
|--------------------+------+-----+-------|
| RENAME=expr | | | X |
|--------------------+------+-----+-------|
| [NO]RETRY | X | X | |
|--------------------+------+-----+-------|
| REWIND | X | X | X |
|--------------------+------+-----+-------|
| SKIPFILE=intexpr | | X | |
|--------------------+------+-----+-------|
| SOCKET | | X | X |
|--------------------+------+-----+-------|
| SPACE=intexpr | | X | X |
|--------------------+------+-----+-------|
| [NO]STREAM | X | | |
|--------------------+------+-----+-------|
| SYSTEM=expr | X | | X |
|--------------------+------+-----+-------|
| TERMINATOR=expr | | X | |
|--------------------+------+-----+-------|
| TIMEOUT=expr | | | X |
|--------------------+------+-----+-------|
| [NO]TRUNCATE | X | X | |
|--------------------+------+-----+-------|
| [NO]TTSYNC | | X | |
|--------------------+------+-----+-------|
| [NO]TYPEAHEAD | | X | |
|--------------------+------+-----+-------|
| UIC=expr | X | | X |
|--------------------+------+-----+-------|
| UPSCROLL | | X | |
|--------------------+------+-----+-------|
| VARIABLE | X | | |
|--------------------+------+-----+-------|
| [Z]WIDTH=intexpr | | X | |
|--------------------+------+-----+-------|
| WORLD=expr | X | | X |
|--------------------+------+-----+-------|
| [Z][NO]WRAP | X | X | |
|--------------------+------+-----+-------|
| WRITELB=expr | | X | |
|--------------------+------+-----+-------|
| X=intexpr | | X | |
|--------------------+------+-----+-------|
| Y=intexpr | | X | |
|--------------------+------+-----+-------|
| ZBFSIZE | X | X | |
|--------------------+------+-----+-------|
| Z[NO]DELAY | X | X | |
|--------------------+------+-----+-------|
| Z[NO]FF | X | X | |
|--------------------+------+-----+-------|
| ZIBFSIZE | X | X | |
|--------------------+------+-----+-------|
| LISTEN=expr | X | X | |
+-----------------------------------------+
1 Utility_Routines
Utility Routines
GT.M provides library utilities to perform frequently used tasks, and to
access frequently used information. Most of the utilities are for GT.M
programmers, but some provide tools for system administration and
operation.
The GT.M distribution includes the source files for these utilities. The
default installation compiles them to produce object modules in the
$gtm_dist distribution library.
You may wish to examine the utilities and include some of them in your
programs if the programs access the function frequently or you may want to
modify the utilities to better fit your particular needs. If you modify a
utility, store your copy in a directory that precedes gtm_dist in the
search list $ZROUTINES to prevent a new release of GT.M from overwriting
your copy.
2 Using_the_Utilities
Using the Utilities
You can either use a utility in Direct Mode or include it in a source
application program with one or more of the following formats.
* DO ^%UTILITYNAME
* DO LABEL^%UTILITYNAME
* $$FUNC^%UTILITYNAME[(para1,...)]
Many utilities contain labels that invoke variations of the basic utility
functionality. Some also provide the label FUNC to invoke an extrinsic
function with optional or required parameters.
Example:
GTM>SET %ds="11/22/2010"
GTM>DO INT^%DATE
GTM>ZWRITE
%DN=62047
%ds="11/22/2010"
3 GT.M_Utilities_Summary_Table
GT.M Utilities Summary Table
+------------------------------------------------------------------------+
| GT.M Utilities Summary |
|------------------------------------------------------------------------|
| UTILITY NAME | DESCRIPTION |
|--------------+---------------------------------------------------------|
| %D | Displays the current date in [d]d-mmm-[yy]yy format. |
|--------------+---------------------------------------------------------|
| %DATE | Converts input date to $HOROLOG format. |
|--------------+---------------------------------------------------------|
| %DH | Converts decimal numbers to hexadecimal. |
|--------------+---------------------------------------------------------|
| %DO | Converts decimal numbers to octal. |
|--------------+---------------------------------------------------------|
| %EXP | Raises number to the power of another number. |
|--------------+---------------------------------------------------------|
| %FL | Lists comment lines at the beginning of the source |
| | programs. |
|--------------+---------------------------------------------------------|
| %FREECNT | Displays the number of free blocks in the database |
| | files associated with the current global directory. |
|--------------+---------------------------------------------------------|
| %G | Displays global variables and their values. |
|--------------+---------------------------------------------------------|
| %GBLDEF | Manipulates the collation sequence assigned to a |
| | global. |
|--------------+---------------------------------------------------------|
| %GC | Copies a global or global sub-tree. |
|--------------+---------------------------------------------------------|
| %GCE | Replaces a specified value or part of a value in a set |
| | of global variables. |
|--------------+---------------------------------------------------------|
| | Displays existing globals in the current global |
| %GD | directory without displaying their values or |
| | descendants. |
|--------------+---------------------------------------------------------|
| %GED | Provides full-screen editing capabilities for global |
| | variables and values. |
|--------------+---------------------------------------------------------|
| %GI | Enters global variables and their values from a |
| | sequential file into a database. |
|--------------+---------------------------------------------------------|
| %GO | Copies globals from the current database to a |
| | sequential output file. |
|--------------+---------------------------------------------------------|
| %GSE | Displays global variables and their values when the |
| | values contain a specified string or number. |
|--------------+---------------------------------------------------------|
| %GSEL | Selects globals by name. |
|--------------+---------------------------------------------------------|
| %H | Converts date and time to and from $HOROLOG format. |
|--------------+---------------------------------------------------------|
| %HD | Converts hexadecimal numbers to decimal. |
|--------------+---------------------------------------------------------|
| %HEX2UTF | Converts the given bytestream in hexadecimal notation |
| | to GT.M encoded character string. |
|--------------+---------------------------------------------------------|
| %HO | Converts hexadecimal numbers to octal. |
|--------------+---------------------------------------------------------|
| %LCASE | Converts a string to all lower case. |
|--------------+---------------------------------------------------------|
| %LCLCOL | Manipulates the collation sequence assigned to local |
| | variables. |
|--------------+---------------------------------------------------------|
| %OD | Converts octal numbers to decimal. |
|--------------+---------------------------------------------------------|
| %OH | Converts octal numbers to hexadecimal. |
|--------------+---------------------------------------------------------|
| %PATCODE | Loads pattern definition files for use within an active |
| | database. |
|--------------+---------------------------------------------------------|
| %RCE | Replaces every occurrence of a text string with another |
| | string in a routine or list of routines. |
|--------------+---------------------------------------------------------|
| %RD | Lists routine names available through your $ZROUTINES |
| | search list. |
|--------------+---------------------------------------------------------|
| %RI | Transfers routines from ANSI sequential format into |
| | individual .m files in GT.M format. |
|--------------+---------------------------------------------------------|
| %RO | Writes M routines in ANSI transfer format. |
|--------------+---------------------------------------------------------|
| %RSE | Searches for every occurrence of a text string in a |
| | routine or a list of routines. |
|--------------+---------------------------------------------------------|
| %RSEL | Selects M routines and places their directories and |
| | names in a local array. |
|--------------+---------------------------------------------------------|
| %SQROOT | Calculates the square root of a number. |
|--------------+---------------------------------------------------------|
| %T | Displays the current time in [h]h:mm AM/PM format. |
|--------------+---------------------------------------------------------|
| %TI | Converts time to $HOROLOG format. |
|--------------+---------------------------------------------------------|
| %TO | Converts the current time from $HOROLOG format to |
| | [h]h:mm AM/PM format. |
|--------------+---------------------------------------------------------|
| %UCASE | Converts a string to all upper case. |
|--------------+---------------------------------------------------------|
| %UTF2HEX | Converts UTF-8 encoded GT.M character string to |
| | bytestream in hexadecimal notation. |
+------------------------------------------------------------------------+
1 Integrate_External
Integrate External
2 Introduction
Introduction
Application code written in M can call application code written in C (or
which uses a C compatible call) and vice versa.
**Note**
This C code shares the process address space with the GT.M run-time
library and M application code. Bugs in C code may result in difficult to
diagnose failures to occur in places not obviously related to the cause of
the failure.
2 Access_Non-M_Routines
Access Non-M Routines
In GT.M, calls to C language routines may be made with the following
syntax:
DO &[packagename.]name[^name][parameter-list]
or as an expression element,
$&[packagename.]name[^name][parameter-list]
Where packagename, like the name elements is a valid M name. Because of
the parsing conventions of M, the identifier between the ampersand (&) and
the optional parameter-list has precisely constrained punctuation - a
later section describes how to transform this into a more richly
punctuated name should that be appropriate for the called function. While
the intent of the syntax is to permit the name^name to match an M
labelref, there is no semantic implication to any use of the up-arrow (^).
Example:
;Call external routine rtn1
DO &rtn1
;Call int^exp in package "mathpak" with one parameter: the expression val/2
DO &mathpak.int^exp(val/2)
;Call the routine sqrt with the value "2"
WRITE $&sqrt(2)
;Call the routine get parms, with the parameter "INPUT" and the variable "inval", passed by reference.
DO &getparms("INPUT",.inval)
;Call program increment in package "mathpak" without specifying a value for the first argument and the variable "outval" passed by reference as the second argument. All arguments which do not specify a value translate to default values in the increment program.
Do &mathpak.increment(,.outval)
The called routines follow the C calling conventions. They must be
compiled as position independent code and linked as a shareable library.
2 Create_Shareable_Library
Create Shareable Library
The method of creating a shareable library varies by the operating system.
The following examples illustrate the commands to be used on an HP-UX
system, a Hewlett-Packard UNIX system, and an IBM pSeries (formerly
RS/6000) AIX system.
Example:
$ cat increment.c
int increment(int count, float *invar, float *outvar)
{
*outvar=*invar+1.0;
return 0;
}
$ cat decrement.c
int decrement(int count, float *invar, float *outvar)
{
*outvar=*invar-1.0;
return 0;
}
On HP-UX:
Example:
$ cc -Aa -c +z -I$gtm_dist increment.c
decrement.c
$ ld -b -o libcrement.sl increment.o
decrement.o -lc
**Note**
Refer to the "Programming on HP-UX" manual for information on shareable
libraries under HP-UX.
On Hewlett-Packard Tru64 UNIX:
Example:
$ cc -c -xtaso -xtaso_short -I$gtm_dist increment.c decrement.c
$ ld -shared -taso -o libcrement.sl increment.o derement.o -lc
**Note**
Refer to the "Tru64 Programmer's Guide" for information on shareable
libraries under HP UNIX.
On IBM pSeries AIX:
Example:
$ cc -c -I$gtm_dist increment.c decrement.c
$ ld -o libcrement.so increment.o decrement.o -G -bexpall -bnoentry -bh:4 -lc
**Note**
Refer to the AIX V4.2 documentation of the ld(1) AIX command for
information on shareable libraries under AIX V4.2.
On Sun Solaris (Solaris 2.6 & higher):
Example:
%/opt/SUNWspro/bin/cc -c -KPIC -I$gtm_dist increment.c decrement.c
% ld -o libcrement.so -G increment.o decrement -lc
On Linux x86:
Example:
% gcc -c -fPIC -I$gtm_dist increment.c decrement.c
% gcc -o libcrement.so -shared increment.o decrement.o
2 External_Calls
External Calls
The functions in programs increment and decrement are now available to
GT.M through the shareable library libcrement.sl or libcrement.so, or
though the DLL as libcrement.dll, depending on the specific platform. The
suffix .sl is used throughout the following examples to represent .sl,
.so, or .dll. Be sure to use the appropriate suffix for your platform.
GT.M uses an "external call table" to map the typeless data of M into the
typed data of C, and vice versa. The external call table has a first line
containing the pathname of the shareable library file followed by one or
more specification lines in the following format:
entryref: return-value routine-name (parameter, parameter, ... )
where entryref is an M entryref,
return-value is gtm_long_t, gtm_status_t, or void.
and
parameters are in the format: direction:type [num]
where [num] indicates a pre-allocation value explained later in this
chapter.
Legal directions are I, O, or IO for input, output, or input/output,
respectively.
The following table describes the legal types defined in the C header file
$gtm_dist/gtmxc_types.h:
Type : Usage
Void: Specifies that the function does not return a value.
gtm_status_t : Type int. If the function returns zero (0), then the call
was successful. If it returns a non-zero value, GT.M will signal an error
upon returning to M.
gtm_long_t : 32-bit signed integer on 32-bit platforms and 64-bit signed
integer on 64-bit platforms (except on Tru64 UNIX where GT.M remains a
32-bit application).
gtm_ulong_t : 32-bit unsigned integer on 32-bit platforms and 64-bit
signed integer on 64-bit platforms.
gtm_long_t* : For passing a pointer to long [integers].
gtm_float_t* : For passing a pointer to floating point numbers.
gtm_double_t* : Same as above, but double precision.
gtm_char_t*: For passing a "C" style string - null terminated.
gtm_char_t** : For passing a pointer to a "C" style string.
gtm_string_t* : For passing a structure in the form {int length;char
*address}. Useful for moving blocks of memory to or from GT.M.
gtm_pointertofunc_t : For passing callback function pointers.
**Note**
If an external call's function argument is defined in the external call
table, GT.M allows invoking that function without specifying a value of
the argument. All non-trailing and output-only arguments arguments which
do not specify a value translate to the following default values in C:
o All numeric types: 0
o gtm_char_t * and gtm_char_t **: Empty string
o gtm_string_t *: A structure with 'length' field matching the
preallocation size and 'address' field being a NULL pointer.
In the mathpak package example, the following invocation translate inval
to the default value, that is, 0.
GTM>do &mathpak.increment(,.outval)
If an external call's function argument is defined in the external call
table and that function is invoked without specifying the argument, ensure
that the external call function appropriately handles the missing
argument. As a good programming practice, always ensure that count of
arguments defined in the external call table matches the function
invocation.
gtmxc_types.h also includes definitions for the following entry points
exported from libgtmshr:
void gtm_hiber_start(gtm_uint_t mssleep);
void gtm_hiber_start_wait_any(gtm_uint_t mssleep)
void gtm_start_timer(gtm_tid_t tid, gtm_int_t time_to_expir, void (*handler)(), gtm_int_t hdata_len, void \*hdata);
void gtm_cancel_timer(gtm_tid_t tid);
where:
* mssleep - milliseconds to sleep
* tid - unique timer id value
* time_to_expir - milliseconds until timer drives given handler
* handler - function pointer to handler to be driven
* hdata_len - 0 or length of data to pass to handler as a parameter
* hdata - NULL or address of data to pass to handler as a parameter
gtm_hiber_start() always sleeps until the time expires;
gtm_hiber_start_wait_any() sleeps until the time expires or an interrupt
by any signal (including another timer). gtm_start_timer() starts a timer
but returns immediately (no sleeping) and drives the given handler when
time expires unless the timer is canceled.
**Important**
GT.M continues to support xc_* equivalent types of gtm_* for upward
compatibility. gtmxc_types.h explicitly marks the xc_* equivalent types as
deprecated.
The first parameter of each called routine is an int (for example, int
argc in decrement.c and increment.c) that specifies the number of
parameters passed. This parameter is implicit and only appears in the
called routine. It does not appear in the call table specification, or in
the M invocation. If there are no explicit parameters, the call table
specification will have a zero (0) value because this value does not
include itself in the count. If there are fewer actual parameters than
formal parameters, the call is determined from the parameters specified by
the values supplied by the M program. The remaining parameters are
undefined. If there are more actual parameters than formal parameters,
GT.M reports an error.
There may be only a single occurrence of the type gtm_status_t for each
entryref.
3 Encryption_Extensions
Encryption Extensions
To support Database Encryption, GT.M provides a reference implementation
which resides in $gtm_dist/plugin/gtmcrypt.
The reference implementation includes:
* A $gtm_dist/plugin/gtmcrypt sub-directory with all source files and
scripts. The scripts include those needed to build/install
libgtmcrypt.so and "helper" scripts, for example, add_db_key.sh (see
below).
* The plugin interface that GT.M expects is defined in
gtmcrypt_interface.h. Never modify this file - it defines the
interface that the plugin must provide.
* $gtm_dist/plugin/libgtmcrypt.so is the shared library containing the
executables which is dynamically linked by GT.M and which in turn
calls the encryption packages. If the $gtm_dist/utf8 directory exists,
then it should contain a symbolic link to ../plugin.
* Source code is provided in the file
$gtm_dist/plugin/gtmcrypt/source.tar which includes build.sh and
install.sh scripts to respectively compile and install libgtmcrypt.so
from the source code.
To support the implementation of a reference implementation, GT.M provides
additional C structure types (in the gtmxc_types.h file):
* gtmcrypt_key_t - a datatype that is a handle to a key. The GT.M
database engine itself does not manipulate keys. The plug-in keeps the
keys, and provides handles to keys that the GT.M database engine uses
to refer to keys.
* xc_fileid_ptr_t - a pointer to a structure maintained by GT.M to
uniquely identify a file. Note that a file may have multiple names -
not only as a consequence of absolute and relative path names, but
also because of symbolic links and also because a file system can be
mounted at more than one place in the file name hierarchy. GT.M needs
to be able to uniquely identify files.
Although not required to be used by a customized plugin implementation,
GT.M provides (and the reference implementation uses) the following
functions for uniquely identifying files:
* xc_status_t gtm_filename_to_id(xc_string_t *filename, xc_fileid_ptr_t
*fileid) - function that takes a file name and provides the file id
structure for that file.
* xc_status_t gtm_is_file_identical(xc_fileid_ptr_t fileid1,
xc_fileid_ptr_t fileid2) - function that determines whether two file
ids map to the same file.
* gtm_xcfileid_free(xc_fileid_ptr_t fileid) - function to release a file
id structure.
Mumps, MUPIP and DSE processes dynamically link to the plugin interface
functions that reside in the shared library. The functions serve as
software "shims" to interface with an encryption library such as libmcrypt
or libgpgme / libgcrypt.
The plugin interface functions are:
* gtmcrypt_init()
* gtmcrypt_getkey_by_name()
* gtmcrypt_getkey_by_hash()
* gtmcrypt_hash_gen()
* gtmcrypt_encode()
* gtmcrypt_decode()
* gtmcrypt_close()
* and gtmcrypt_strerror()
A GT.M database consists of multiple database files, each of which has its
own encryption key, although you can use the same key for multiple files.
Thus, the gtmcrypt* functions are capable of managing multiple keys for
multiple database files. Prototypes for these functions are in
gtmcrypt_interface.h.
The core plugin interface functions, all of which return a value of type
gtm_status_t are:
* gtmcrypt_init() performs initialization. If the environment variable
$gtm_passwd exists and has an empty string value, GT.M calls
gtmcrypt_init() before the first M program is loaded; otherwise it
calls gtmcrypt_init() when it attempts the first operation on an
encrypted database file.
* Generally, gtmcrypt_getkey_by_hash or, for MUPIP CREATE,
gtmcrypt_getkey_by_name perform key acquisition, and place the keys
where gtmcrypt_decode() and gtmcrypt_encode() can find them when they
are called.
* Whenever GT.M needs to decode a block of bytes, it calls
gtmcrypt_decode() to decode the encrypted data. At the level at which
GT.M database encryption operates, it does not matter what the data is
- numeric data, string data whether in M or UTF-8 mode and whether or
not modified by a collation algorithm. Encryption and decryption
simply operate on a series of bytes.
* Whenever GT.M needs to encode a block of bytes, it calls
gtmcrypt_encode() to encode the data.
* If encryption has been used (if gtmcrypt_init() was previously called
and returned success), GT.M calls gtmcrypt_close() at process exit and
before generating a core file. gtmcrypt_close() must erase keys in
memory to ensure that no cleartext keys are visible in the core file.
More detailed descriptions follow.
* gtmcrypt_key_t *gtmcrypt_getkey_by_name(gtm_string_t *filename) -
MUPIP CREATE uses this function to get the key for a database file.
This function searches for the given filename in the memory key ring
and returns a handle to its symmetric cipher key. If there is more
than one entry for the given filename , the reference implementation
returns the entry matching the last occurrence of that filename in the
master key file.
* gtm_status_t gtmcrypt_hash_gen(gtmcrypt_key_t *key, gtm_string_t
*hash) - MUPIP CREATE uses this function to generate a hash from the
key then copies that hash into the database file header. The first
parameter is a handle to the key and the second parameter points to
256 byte buffer. In the event the hash algorithm used provides hashes
smaller than 256 bytes, gtmcrypt_hash_gen() must fill any unused space
in the 256 byte buffer with zeros.
* gtmcrypt_key_t *gtmcrypt_getkey_by_hash(gtm_string_t *hash) - GT.M
uses this function at database file open time to obtain the correct
key using its hash from the database file header. This function
searches for the given hash in the memory key ring and returns a
handle to the matching symmetric cipher key. MUPIP LOAD, MUPIP
RESTORE, MUPIP EXTRACT, MUPIP JOURNAL and MUPIP BACKUP -BYTESTREAM all
use this to find keys corresponding to the current or prior databases
from which the files they use for input were derived.
* gtm_status_t gtmcrypt_encode(gtmcrypt_key_t *key, gtm_string_t *inbuf,
gtm_string_t *outbuf) and gtm_status_t gtmcrypt_decode(gtmcrypt_key_t
*key, gtm_string_t *inbuf, gtm_string_t *outbuf)- GT.M uses these
functions to encode and decode data. The first parameter is a handle
to the symmetric cipher key, the second a pointer to the block of data
to encode or decode, and the third a pointer to the resulting block of
encoded or decoded data. Using the appropriate key (same key for a
symmetric cipher), gtmcrypt_decode() must be able to decode any data
buffer encoded by gtmcrypt_encode(), otherwise the encrypted data is
rendered unrecoverable.7 As discussed earlier, GT.M requires the
encrypted and cleartext versions of a string to have the same length.
* char *gtmcrypt_strerror() - GT.M uses this function to retrieve
addtional error context from the plug-in after the plug-in returns an
error status. This function returns a pointer to additional text
related to the last error that occurred. GT.M displays this text as
part of an error report. In a case where an error has no additional
context or description, this function returns a null string.
The complete source code for reference implementations of these functions
is provided, licensed under the same terms as GT.M. You are at liberty to
modify them to suit your specific GT.M database encryption needs. Check
your GT.M license if you wish to consider redistributing your changes to
others.
For more information and examples, refer to the Database Encryption
Technical Bulletin.
3 Pre-allocation
Pre-allocation
The definition of parameters passed by reference with direction output can
include specification of a pre-allocation value. This is the number of
units of memory that the user wants GT.M to allocate before passing the
parameter to the external routine. For example, in the case of type
gtm_char_t *, the pre-allocation value would be the number of bytes to be
allocated before the call to the external routine.
Specification of a pre-allocation value should follow these rules:
* Pre-allocation is an unsigned integer value specifying the number of
bytes to be allocated on the system heap with a pointer passed into
the external call.
* Pre-allocating on a type with a direction of input or input/output
results in a GT.M error.
* Pre-allocation is meaningful only on types gtm_char_t * and
gtm_string_t *. On all other types the pre-allocation value specified
will be ignored and the parameter will be allocated a default value
for that type. With gtm_string_t * arguments make sure to set the
'length' field appropriately before returning control to GT.M. On
return from the external call, GT.M uses the value in the length field
as the length of the returned value, in bytes.
* If the user does not specify any value, then the default
pre-allocation value would be assigned to the parameter.
* Specification of pre-allocation for "scalar" types (parameters which
are passed by value) is an error.
**Important**
Pre-allocation is optional for all output-only parameters except
gtm_string_t * and gtm_char_t *. Pre-allocation yields better management
of memory for the external call.
3 Callback_Mechanism
Callback Mechanism
GT.M exposes certain functions that are internal to the GT.M runtime
library for the external calls via a callback mechanism. While making an
external call, GT.M populates and exposes a table of function pointers
containing addresses to call-back functions.
+-----------------------------------------------------------------------------+
|Index| Function | Argument | Type | Description |
|-----+--------------------+--------------+----------+------------------------|
|0 |hiber_start | | |sleep for a specified |
| | | | |time |
|-----+--------------------+--------------+----------+------------------------|
| | |slp_time |integer |milliseconds to sleep |
|-----+--------------------+--------------+----------+------------------------|
| | | | |sleep for a specified |
|1 |hiber_start_wait_any| | |time or until any |
| | | | |interrupt, whichever |
| | | | |comes first |
|-----+--------------------+--------------+----------+------------------------|
| | |slp_time |integer |milliseconds to sleep |
|-----+--------------------+--------------+----------+------------------------|
| | | | |start a timer and invoke|
|2 |start_timer | | |a handler function when |
| | | | |the timer expires |
|-----+--------------------+--------------+----------+------------------------|
| | | | |unique user specified |
| | |tid |integer |identifier for this |
| | | | |timer |
|-----+--------------------+--------------+----------+------------------------|
| | |time_to_expire|integer |milliseconds before |
| | | | |handler is invoked |
|-----+--------------------+--------------+----------+------------------------|
| | | |pointer to|specifies the entry of |
| | |handler |function |the handler function to |
| | | | |invoke |
|-----+--------------------+--------------+----------+------------------------|
| | | | |length of data to be |
| | |hlen |integer |passed via the hdata |
| | | | |argument |
|-----+--------------------+--------------+----------+------------------------|
| | |hdata |pointer to|data (if any) to pass to|
| | | |char |the handler function |
|-----+--------------------+--------------+----------+------------------------|
| | | | |stop a timer previously |
|3 |cancel_timer | | |started with |
| | | | |start_timer(), if it has|
| | | | |not yet expired |
|-----+--------------------+--------------+----------+------------------------|
| | | | |unique user specified |
| | |tid |integer |identifier of the timer |
| | | | |to cancel |
|-----+--------------------+--------------+----------+------------------------|
|4 |gtm_malloc | | |allocates process memory|
| | | | |from the heap |
|-----+--------------------+--------------+----------+------------------------|
| | |<return-value>|pointer to|address of the allocated|
| | | |void |space |
|-----+--------------------+--------------+----------+------------------------|
| | | |32-bit | |
| | | |platforms:| |
| | | |32-bit | |
| | | |unsigned |bytes of space to |
| | | |integer |allocate. This has the |
| | |space_needed | |same signature as the |
| | | |64-bit |system malloc() call. |
| | | |platforms:| |
| | | |64-bit | |
| | | |unsigned | |
| | | |integer | |
|-----+--------------------+--------------+----------+------------------------|
| | | | |return memory previously|
|5 |gtm_free | | |allocated with |
| | | | |gtm_malloc() |
|-----+--------------------+--------------+----------+------------------------|
| | | |pointer to|address of the |
| | |free_address |void |previously allocated |
| | | | |space |
+-----------------------------------------------------------------------------+
The external routine can access and invoke a call-back function in any of
the following mechanisms:
* While making an external call, GT.M sets the environment variable
GTM_CALLIN_START to point to a string containing the start address
(decimal integer value) of the table described above. The external
routine needs to read this environment variable, convert the string
into an integer value and should index into the appropriate entry to
call the appropriate GT.M function.
* GT.M also provides an input-only parameter type gtm_pointertofunc_t
that can be used to obtain call-back function pointers via parameters
in the external routine. If a parameter is specified as
I:gtm_pointertofunc_t and if a numeric value (between 0-5) is passed
for this parameter in M, GT.M interprets this value as the index into
the callback table and passes the appropriate callback function
pointer to the external routine.
**Note**
FIS strongly discourages the use of signals, especially SIGALARM, in user
written C functions. GT.M assumes that it has complete control over any
signals that occur and depends on that behavior for recovery if anything
should go wrong. The use of exposed timer APIs should be considered for
timer needs.
3 Limitations
Limitations
Since both GT.M runtime environment and the external C functions execute
in the same process space, the following restrictions apply to the
external functions:
1. GT.M is designed to use signals and has signal handlers that must
function for GT.M to operate properly. The timer related call-backs
should be used in place of any library or system call which uses
SIGALRM such as sleep(). Use of signals by external call code may
cause GT.M to fail.
2. Use of the GT.M provided malloc and free, creates an integrated heap
management system, which has a number of debugging tools. FIS
recommends the usage of gtm_malloc/gtm_free in the external functions
that provides better debugging capability in case memory management
problems occur with external calls.
3. Use of exit system call in external functions is strongly discouraged.
Since GT.M uses exit handlers to properly shutdown runtime environment
and any active resources, the system call _exit should never be used
in external functions.
4. GT.M uses timer signals so often that the likelihood of a system call
being interrupted is high. So, all system calls in the external
program can return EINTR if interrupted by a signal.
5. Handler functions invoked with start_timer must not invoke services
that are identified by the Operating System documentation as unsafe
for signal handlers (or not identified as safe) - consult the system
documentation or man pages for this information. Such services cause
non-deterministic failures when they are interrupted by a function
that then attempts to call them, wrongly assuming they are reentrant.
3 Examples
Examples
foo: void bar (I:gtm_float_t*, O:gtm_float_t*)
There is one external call table for each package. The environment
variable "GTMXC" must name the external call table file for the default
package. External call table files for packages other than the default
must be identified by environment variables of the form "GTMXC_name".
The first of the external call tables is the location of the shareable
library. The location can include environment variable names.
Example:
% echo $GTMXC_mathpak
/user/joe/mathpak.xc
% echo lib /usr/
% cat mathpak.xc
$lib/mathpak.sl
exp: gtm_status_t xexp(I:gtm_float_t*, O:gtm_float_t*)
% cat exp.c
...
int xexp(count, invar, outvar)
int count;
float *invar;
float *outvar;
{
...
}
% gtm
...
GTM>d &mathpak.exp(inval,.outval)
GTM>
Example : For preallocation:
% echo $GTMXC_extcall
/usr/joe/extcall.xc
% cat extcall.xc
/usr/lib/extcall.sl
prealloc: void gtm_pre_alloc_a(O:gtm_char_t *[12])
% cat extcall.c
#include <stdio.h>
#include <string.h>
#include "gtmxc_types.h"
void gtm_pre_alloc_a (int count, char *arg_prealloca)
{
strcpy(arg_prealloca, "New Message");
return;
}
Example : for call-back mechanism
% echo $GTMXC
/usr/joe/callback.xc
% cat /usr/joe/callback.xc
$MYLIB/callback.sl
init: void init_callbacks()
tstslp: void tst_sleep(I:gtm_long_t)
strtmr: void start_timer(I:gtm_long_t, I:gtm_long_t)
% cat /usr/joe/callback.c
#include <stdio.h>
#include <stdlib.h>
#include "gtmxc_types.h"
void **functable;
void (*setup_timer)(int , int , void (*)() , int , char *);
void (*cancel_timer)(int );
void (*sleep_interrupted)(int );
void (*sleep_uninterrupted)(int );
void* (*malloc_fn)(int);
void (*free_fn)(void*);
void init_callbacks (int count)
{
char *start_address;
start_address = (char *)getenv("GTM_CALLIN_START");
if (start_address == (char *)0)
{
fprintf(stderr,"GTM_CALLIN_START is not set\n");
return;
}
functable = (void **)atoi(start_address);
if (functable == (void **)0)
{
perror("atoi : ");
fprintf(stderr,"addresses defined by GTM_CALLIN_START not a number\n");
return;
}
sleep_uninterrupted = (void (*)(int )) functable[0];
sleep_interrupted = (void (*)(int )) functable[1];
setup_timer = (void (*)(int , int, void (*)(), int, char *)) functable[2];
cancel_timer = (void (*)(int )) functable[3];
malloc_fn = (void* (*)(int)) functable[4];
free_fn = (void (*)(void*)) functable[5];
return;
}
void sleep (int count, int time)
{
(*sleep_uninterrupted)(time);
}
void timer_handler ()
{
fprintf(stderr,"Timer Handler called\n");
/* Do something */
}
void start_timer (int count, int time_to_int, int time_to_sleep)
{
(*setup_timer)((int )start_timer, time_to_int, timer_handler, 0, 0);
return;
}
void* xmalloc (int count)
{
return (*malloc_fn)(count);
}
void xfree(void* ptr)
{
(*free_fn)(ptr);
}
Example:gtm_malloc/gtm_free callbacks using gtm_pointertofunc_t
% echo $GTMXC
/usr/joe/callback.xc
% cat /usr/joe/callback.xc
/usr/lib/callback.sl
init: void init_callbacks(I:gtm_pointertofunc_t, I:gtm_pointertofunc_t)
% gtm
GTM> do &.init(4,5)
GTM>
% cat /usr/joe/callback.c
#include <stdio.h>
#include <stdlib.h>
#include "gtmxc_types.h"
void* (*malloc_fn)(int);
void (*free_fn)(void*);
void init_callbacks(int count, void* (*m)(int), void (*f)(void*))
{
malloc_fn = m;
free_fn = f;
}
2 Call-Ins
Call-Ins
Call-In is a framework supported by GT.M that allows a C/C++ program to
invoke an M routine within the same process context. GT.M provides a
well-defined Call-In interface packaged as a run-time shared library that
can be linked into an external C/C++ program.
3 Relevant_files
Relevant files
To facilitate Call-Ins to M routines, the GT.M distribution directory
($gtm_dist) contains the following files:
1. libgtmshr.so - A shared library that implements the GT.M run-time
system, including the Call-In API. If Call-Ins are used from a
standalone C/C++ program, this library needs to be explicitly linked
into the program.
**Note**
.so is the recognized shared library file extension on most UNIX
platforms, except on HP-UX, wherein it is .sl.
2. mumps - The GT.M startup program that dynamically links with
libgtmshr.so.
3. gtmxc_types.h - A C-header file containing the declarations of Call-In
API.
The following sections describe the files relevant to using Call-Ins.
5 gtmxc_types.h
gtmxc_types.h
The header file provides signatures of all Call-In interface functions and
definitions of those valid data types that can be passed from C to M. FIS
strongly recommends that these types be used instead of native types (int,
char, float, and so on), to avoid possible mismatch problems during
parameter passing.
gtmxc_types.h defines the following types that can be used in Call-Ins.
+------------------------------------------------------------------------+
| Type | Usage |
|--------------+---------------------------------------------------------|
| void | Used to express that there is no function return value |
|--------------+---------------------------------------------------------|
| gtm_int_t | gtm_int_t has 32-bit length on all platforms. |
|--------------+---------------------------------------------------------|
| gtm_uint_t | gtm_uint_t has 32-bit length on all platforms |
|--------------+---------------------------------------------------------|
| | gtm_long_t has 32-bit length on 32-bit platforms and |
| gtm_long_t | 64-bit length on 64-bit platforms. It is much the same |
| | as the C language long type, except on Tru64 UNIX, |
| | where GT.M remains a 32-bit application. |
|--------------+---------------------------------------------------------|
| gtm_ulong_t | gtm_ulong_t is much the same as the C language unsigned |
| | long type. |
|--------------+---------------------------------------------------------|
| gtm_float_t | floating point number |
|--------------+---------------------------------------------------------|
| gtm_double_t | Same as above but double precision. |
|--------------+---------------------------------------------------------|
| | type int. If it returns zero then the call was |
| gtm_status_t | successful. If it is non-zero, when control returns to |
| | GT.M, it issues a trappable error. |
|--------------+---------------------------------------------------------|
| gtm_long_t* | Pointer to gtm_long_t. Good for returning integers. |
|--------------+---------------------------------------------------------|
| gtm_ulong_t* | Pointer to gtm_ulong_t. Good for returning unsigned |
| | integers. |
+------------------------------------------------------------------------+
typedef struct {
gtm_long_t length;
gtm_char_t* address;
} gtm_string_t;
The pointer types defined above are 32-bit addresses on all 32-platforms
(including Tru64 UNIX where GT.M remains a 32-bit application). For other
64-bit platforms, gtm_string_t* is a pointer is a 64-bit address.
gtmxc_types.h also provides an input-only parameter type
gtm_pointertofunc_t that can be used to obtain call-back function pointers
via parameters in the external routine. If a parameter is specified as
I:gtm_pointertofunc_t and if a numeric value (between 0-5) is passed for
this parameter in M, GT.M interprets this value as the index into the
callback table and passes the appropriate callback function pointer to the
external routine.
**Note**
GT.M represents values that fit in 18 digits as numeric values, and values
that require more than 18 digits as strings.
gtmxc_types.h also includes definitions for the following entry points
exported from libgtmshr:
void gtm_hiber_start(gtm_uint_t mssleep);
void gtm_hiber_start_wait_any(gtm_uint_t mssleep)
void gtm_start_timer(gtm_tid_t tid, gtm_int_t time_to_expir, void (*handler)(), gtm_int_t hdata_len, void \*hdata);
void gtm_cancel_timer(gtm_tid_t tid);
where:
* mssleep - milliseconds to sleep
* tid - unique timer id value
* time_to_expir - milliseconds until timer drives given handler
* handler - function pointer to handler to be driven
* hdata_len - 0 or length of data to pass to handler as a parameter
* hdata - NULL or address of data to pass to handler as a parameter
gtm_hiber_start() always sleeps until the time expires;
gtm_hiber_start_wait_any() sleeps until the time expires or an interrupt
by any signal (including another timer). gtm_start_timer() starts a timer
but returns immediately (no sleeping) and drives the given handler when
time expires unless the timer is canceled.
**Important**
GT.M continues to support xc_* equivalent types of gtm_* for upward
compatibility. gtmxc_types.h explicitly marks the xc_* equivalent types as
deprecated.
4 Call-In_Table
Call-In Table
The Call-In table file is a text file that contains the signatures of all
M label references that get called from C. In order to pass the typed C
arguments to the type-less M formallist, the enviroment variable GTMCI
must be defined to point to the Call-In table file path. Each signature
must be specified separately in a single line. GT.M reads this file and
interprets each line according to the following convention (specifications
withint box brackets "[]", are optional):
<c-call-name> : <ret-type> <label-ref> ([<direction>:<param-type>,...])
where,
<label-ref>: is the entry point (that is a valid label reference) at which
GT.M starts executing the M routine being called-in
<c-call-name>: is a unique C identifier that is actually used within C to
refer to <label-ref>
<direction>: is either I (input-only), O (output-only), or IO
(input-output)
<ret-type>: is the return type of <label-ref>
**Note**
Since the return type is considered as an output-only (O) parameter, the
only types allowed are pointer types and void. Void cannot be specified as
parameter.
<param-type>: is a valid parameter type. Empty parenthese must be
specified if no argument is passed to <label-ref>
The <direction> indicates the type of operation that GT.M performs on the
parameter read-only (I), write-only (O), or read-write (IO). All O and IO
parameters must be passed by reference, that is as pointers since GT.M
writes to these locations. All pointers that are being passed to GT.M must
be pre-allocated. The following table details valid type specifications
for each direction.
+------------------------------------------------------------------------+
| Directions | Allowed Parameter types |
|------------+-----------------------------------------------------------|
| | gtm_long_t, gtm_ulong_t, gtm_float_t, |
| I | gtm_double_t,_gtm_long_t*, gtm_ulong_t*, gtm_float_t*, |
| | gtm_double_t*,_gtm_char_t*, gtm_string_t* |
|------------+-----------------------------------------------------------|
| O/IO | gtm_long_t*, gtm_ulong_t*, gtm_float_t*, |
| | gtm_double_t*,_gtm_char_t*, gtm_string_t* |
+------------------------------------------------------------------------+
Here is an example of Call-In table (calltab.ci) for piece.m:
print :void display^piece()
getpiece :gtm_char_t* get^piece(I:gtm_char_t*, I:gtm_char_t*, I:gtm_long_t)
setpiece :void set^piece(IO:gtm_char_t*, I:gtm_char_t*, I:gtm_long_t, I:gtm_char_t*)
pow :gtm_double_t* pow^piece(I:gtm_double_t, I:gtm_long_t)
powequal :void powequal^piece(IO:gtm_double_t*, I:gtm_long_t)
piece :gtm_double_t* pow^piece(I:gtm_double_t, I:gtm_long_t)
**Note**
The same entryref can be called by different C call names (for example,
pow, and piece). However, if there are multiple lines with the same call
name, only the first entry will be used by GT.M. GT.M ignores all
subsequent entries using a call name. Also, note that the second and third
entries, although shown here as wrapped across lines, must be specified as
a single line in the file.
3 Interface
Interface
This section is further broken down into 6 subsections for an easy
understanding of the Call-In interface. The section is concluded with an
elaborate example.
5 Initialize_GT.M
Initialize GT.M
gtm_status_t gtm_init(void);
If the base program is not an M routine but a standalone C program,
gtm_init() must be called (before calling any GT.M functions), to
initialize the GT.M run-time system.
gtm_init() returns zero (0) on success. On failure, it returns the GT.M
error status code whose message can be read into a buffer by immediately
calling gtm_zstatus(). Duplicate invocations of gtm_init() are ignored by
GT.M.
If Call-Ins are used from an external call function (that is, a C function
that has itself been called from M code), gtm_init() is not needed,
because GT.M is initialized before the External Call. All gtm_init() calls
from External Calls functions are ignored by GT.M.
4 Call_from_C
Call from C
GT.M provides 2 interfaces for calling a M routine from C. These are:
* gtm_cip
* gtm_ci
gtm_cip offers better performance on calls after the first one.
5 gtm_cip
gtm_cip
gtm_status_t gtm_cip(ci_name_descriptor *ci_info, ...);
The variable argument function gtm_cip() is the interface that invokes the
specified M routine and returns the results via parameters.
ci_name_descriptor has the following structure:
typedef struct
{
gtm_string_t rtn_name;
void* handle;
} ci_name_descriptor;
rtn_name is a C character string indicating the corresponding <lab-ref>
entry in the Call-In table.
The handle is GT.M private information initialized by GT.M on the first
call-in and to be provided unmodified to GT.M on subsequent calls. If
application code modifies it, it will corrupt the address space of the
process, and potentially cause just about any bad behavior that it is
possible for the process to cause, including but not limited to process
death, database damage and security violations.
The gtm_cip() call must follow the following format:
status = gtm_cip(<ci_name_descriptor> [, ret_val] [, arg1] ...);
First argument: ci_name_descriptor, a null-terminated C character string
indicating the alias name for the corresponding <lab-ref> entry in the
Call-In table.
Optional second argument: ret_val, a pre-allocated pointer through which
GT.M returns the value of QUIT argument from the (extrinsic) M routine.
ret_val must be the same type as specified for <ret-type> in the Call-In
table entry. The ret_val argument is needed if and only if <ret-type> is
not void.
Optional list of arguments to be passed to the M routine's formallist: the
number of arguments and the type of each argument must match the number of
parameters, and parameter types specified in the corresponding Call-In
table entry. All pointer arguments must be pre-allocated. GT.M assumes
that any pointer, which is passed for O/IO-parameter points to valid
write-able memory.
The status value returned by gtm_cip() indicates the GT.M status code;
zero (0), if successful, or a non-zero; $ZSTATUS error code on failure.
The $ZSTATUS message of the failure can be read into a buffer by
immediately calling gtm_zstatus().
5 gtm_ci
gtm_ci
gtm_status_t gtm_ci(const gtm_char_t* c_call_name, ...);
The variable argument function gtm_ci() is the interface that actually
invokes the specified M routine and returns the results via parameters.
The gtm_ci() call must be in the following format:
status = gtm_ci(<c_call_name> [, ret_val] [, arg1] ...);
First argument: c_call_name, a null-terminated C character string
indicating the alias name for the corresponding <lab-ref> entry in the
Call-In table.
Optional second argument: ret_val, a pre-allocated pointer through which
GT.M returns the value of QUIT argument from the (extrinsic) M routine.
ret_val must be the same type as specified for <ret-type> in the Call-In
table entry. The ret_val argument is needed if and only if <ret-type> is
not void.
Optional list of arguments to be passed to the M routine's formallist: the
number of arguments and the type of each argument must match the number of
parameters, and parameter types specified in the corresponding Call-In
table entry. All pointer arguments must be pre-allocated. GT.M assumes
that any pointer, which is passed for O/IO-parameter points to valid
write-able memory.
The status value returned by gtm_ci() indicates the GT.M status code; zero
(0), if successful, or a non-zero; $ZSTATUS error code on failure. The
$ZSTATUS message of the failure can be read into a buffer by immediately
calling gtm_zstatus().
4 Error_Messages
Error Messages
void gtm_zstatus (gtm_char_t* msg_buffer, gtm_long_t buf_len);
This function returns the null-terminated $ZSTATUS message of the last
failure via the buffer pointed by msg_buffer of size buf_len. The message
is truncated to size buf_len if it does not fit into the buffer.
gtm_zstatus() is useful if the external application needs the text message
corresponding to the last GT.M failure. A buffer of 2048 is sufficient to
fit in any GT.M message.
4 Exit
Exit
gtm_status_t gtm_exit (void);
gtm_exit() can be used to shut down all databases and exit from the GT.M
environment that was created by a previous gtm_init().
Note that gtm_init() creates various GT.M resources and keeps them open
across multiple invocations of gtm_ci() until gtm_exit() is called to
close all such resources. On successful exit, gtm_exit() returns zero (0),
else it returns the $ZSTATUS error code.
gtm_exit() cannot be called from an external call function. GT.M reports
the error GTM-E-INVGTMEXIT if an external call function invokes
gtm_exit(). Since the GT.M run-time system must be operational even after
the external call function returns, gtm_exit() is meant to be called only
once during a process lifetime, and only from the base C/C++ program when
GT.M functions are no longer required by the program.
3 Standalone_Programs
Standalone Programs
All external C functions that use call-ins should include the header file
gtmxc_types.h that defines various types and provides signatures of
call-in functions. To avoid potential size mismatches with the parameter
types, FIS strongly recommends that gtm *t types defined in gtmxc_types.h
be used instead of the native types (int, float, char, etc).
To use call-ins from a standalone C program, it is necessary that the GT.M
runtime library (libgtmshr.so) is explicitly linked into the program. If
call-ins are used from an External Call function (which in turn was called
from GT.M through the existing external call mechanism), the External Call
library does not need to be linked explicitly with libgtmshr.so since GT.M
would have already loaded it.
3 Nested_Call-Ins
Nested Call-Ins
Call-ins can be nested by making an external call function in-turn call
back into GT.M. Each gtm_ci() called from an External Call library creates
a call-in base frame at $ZLEVEL 1 and executes the M routine at $ZLEVEL 2.
The nested call-in stack unwinds automatically when the External Call
function returns to GT.M.
GT.M currently allows up to 10 levels of nesting, if TP is not used, and
less than 10 if GT.M supports call-ins from a transaction. GT.M reports
the error GTM-E-CIMAXLEVELS when the nesting reaches its limit.
Following are the GT.M commands, Intrinsic Special Variables, and
functions whose behavior changes in the context of every new nested
call-in environment.
ZGOTO operates only within the current nested M stack. ZGOTO zero (0)
unwinds all frames in the current nested call-in M stack (including the
call-in base frame) and returns to C. ZGOTO one (1) unwinds all current
stack frame levels up to (but not inclusive) the call-in base frame and
returns to C, while keeping the current nested call-in environment active
for any following gtm_ci() calls.
$ZTRAP/$ETRAP NEW'd at level 1 (in GTM$CI frame).
$ZLEVEL initializes to one (1) in GTM$CI frame, and increments for every
new stack level.
$STACK initializes to zero (0) in GTM$CI frame, and increments for every
new stack level.
$ESTACK NEW'd at level one (1) in GTM$CI frame.
$ECODE/$STACK() initialized to null at level one (1) in GTM$CI frame.
**Note**
After a nested call-in environment exits and the external call C function
returns to M, the above ISVs and Functions restore their old values.
3 Rules_to_Follow_in_Call-Ins
Rules to Follow in Call-Ins
1. External calls must not be fenced with TSTART/TCOMMIT if the external
routine calls back into mumps using call-in mechanism. GT.M reports
the error GTM-E-CITPNESTED if nested call-ins are invoked within a TP
fence since GT.M currently does not handle TP support across multiple
call-in invocations.
2. The external application should never call exit() unless it has called
gtm_exit() previously. GT.M internally installs an exit handler that
should never be bypassed.
3. The external application should never use any signals when GT.M is
active since GT.M reserves them for its internal use. GT.M provides
the ability to handle SIGUSR1 within M. An interface is provided by
GT.M for timers. Although not required, FIS recommends the use of
gtm_malloc() and gtm_free() for memory management by C code that
executes in a GT.M process space for enhanced performance and improved
debugging.
4. GT.M performs device input using the read() system service. UNIX
documentation recommends against mixing this type of input with
buffered input services in the fgets() family and ignoring this
recommendation is likely to cause loss of input that is difficult to
diagnose and understand.
2 Type_Limits_for_Call-ins_and_Call-outs
Type Limits for Call-ins and Call-outs
Depending on the direction (I, O, or IO) of a particular type, both
call-ins and call-outs may transfer a value in two directions as follows:
Call-out: GT.M -> C -> GT.M Call-in: C -> GT.M -> C
| | | | | |
'-----'-----' '-----'-----'
1 2 2 1
In the following table, the GT.M->C limit applies to 1 and the C->GT.M
limit applies to 2. In other words, GT.M->C applies to I direction for
call-outs and O direction for call-ins and C->GT.M applies to I direction
for call-ins and O direction for call-outs.
+------------------------------------------------------------------------+
| | GTM->C | C->GT.M |
|----------------+---------------------------+---------------------------|
| Type | Precision | Range | Precision | Range |
|----------------+-----------+---------------+-----------+---------------|
| gtm_int_t, | Full | [-2^31+1, | Full | [-2^31, |
| gtm_int_t * | | 2^31-1] | | 2^31-1] |
|----------------+-----------+---------------+-----------+---------------|
| gtm_uint_t, | Full | [0, 2^32-1] | Full | [0, 2^32-1] |
| gtm_uint_t * | | | | |
|----------------+-----------+---------------+-----------+---------------|
| gtm_long_t, | | [-2^63+1, | | [-2^63, |
| gtm_long_t * | 18 digits | 2^63-1] | 18 digits | 2^63-1] |
| (64-bit) | | | | |
|----------------+-----------+---------------+-----------+---------------|
| gtm_long_t, | | [-2^31+1, | | [-2^31, |
| gtm_long_t * | Full | 2^31-1] | Full | 2^31-1] |
| (32-bit) | | | | |
|----------------+-----------+---------------+-----------+---------------|
| gtm_ulong_t, | | | | |
| gtm_ulong_t * | 18 digits | [0, 2^64-1] | 18 digits | [0, 2^64-1] |
| (64-bit) | | | | |
|----------------+-----------+---------------+-----------+---------------|
| gtm_ulong_t, | | | | |
| gtm_ulong_t * | Full | [0, 2^32-1] | Full | [0, 2^32-1] |
| (32-bit) | | | | |
|----------------+-----------+---------------+-----------+---------------|
| gtm_float_t, | 6-9 | [1E-43, | 6 digits | [1E-43, |
| gtm_float_t * | digits | 3.4028235E38] | | 3.4028235E38] |
|----------------+-----------+---------------+-----------+---------------|
| gtm_double_t, | 15-17 | [1E-43, 1E47] | 15 digits | [1E-43, 1E47] |
| gtm_double_t * | digits | | | |
|----------------+-----------+---------------+-----------+---------------|
| gtm_char_t * | N/A | ["", 1MiB] | N/A | ["", 1MiB] |
|----------------+-----------+---------------+-----------+---------------|
| gtm_char_t ** | N/A | ["", 1MiB] | N/A | ["", 1MiB] |
|----------------+-----------+---------------+-----------+---------------|
| gtm_string_t * | N/A | ["", 1MiB] | N/A | ["", 1MiB] |
+------------------------------------------------------------------------+
**Note**s
o gtm_char_t ** is not supported for call-ins but they are included for
IO and O direction usage with call-outs.
o For call-out use of gtm_char_t * and gtm_string_t *, the specification
in the interface definition for preallocation sets the range for IO
and O, with a maximum of 1MiB.
1 Internationalization
Internationalization
This chapter describes GT.M facilities for applications using characters
encoded in other than eight-bit bytes (octets). The underlying software
libraries necessary to implement the GT.M internationalization facilities
may not be available on your system. Before continuing with the
implementation provided in this chapter refer to the product release notes
that accompanied your GT.M shipment. These facilities address the specific
issues of defining alternative collation sequences, and defining unique
patterns for use with the pattern match operator. The details of each
facility are described in separate sections of this chapter.
Alternative collation sequences (or an alternative ordering of strings)
can be defined for global and local variable subscripts. They can be
established for specified globals or for an entire database. The
alternative sequences are defined by a series of routines in an executable
file pointed to by an environment variable. As the collation sequence is
implemented by a user-supplied program, virtually any collation policy may
be implemented. Detailed information on establishing alternative collation
sequences and defining the environment variable is provided in Collation
Sequence Definitions.
M has defined pattern classes that serve as arguments to the pattern match
operator. GT.M supports user definition of additional pattern classes as
well as redefinition of the standard pattern classes. Specific patterns
are defined in a text file that is pointed to by an environment variable.
Pattern classes may be re-defined dynamically. The details of defining
these pattern classes and the environment variable are described in the
section called Match Alternative Patterns.
For some languages (such as Chinese), the ordering of strings according to
Unicode code-points (character values) may or may not be the
linguistically or culturally correct ordering. Supporting applications in
such languages requires development of collation modules - GT.M natively
supports M collation, but does not include pre-built collation modules for
any specific natural language. Therefore, applications that use characters
in Unicode may need to implement their own collation functions.
2 Collation_Sequence_Definitions
Collation Sequence Definitions
Normally, GT.M orders data with numeric values first, followed by strings
sequenced by ASCII values. To use an alternative collating sequence the
following items must be provided at GT.M process intialization.
* A shared library containing the routines for each alternative
collation sequence
* An environment variable of the form gtm_collate_n, specifying the
shared library containing the routines for alternative collation
sequence n.
3 Shared_Library
Shared Library
A shared library for an alternative collation sequence must contain the
following four routines:
1. gtm_ac_xform_1: Transforms subscripts up to the maximum supported
string length to the alternative collation sequence, or
gtm_ac_xform: Transforms subscripts up to 32,767 bytes to the
alternative collation sequence.
2. gtm_ac_xback_1: Use with gtm_ac_xform_1 to transform the alternative
collation keys back to the original subscript representation, or
gtm_ac_xback: Use with gtm_ac_xform to transforms the alternative
collation keys back to the original subscript representation.
3. gtm_ac_version: Returns a numeric version identifier for the
"currently active" set of collation routines.
4. gtm_ac_verify: Returns the success (odd) or failure (even) in matching
a collation sequence with a given version number.
GT.M searches the shared library for the gtm_ac_xform_1 and gtm_ac_xback_1
before searching for the gtm_ac_xform and gtm_ac_xback routines. If the
shared library contains gtm_ac_xform_1, GT.M ignores gtm_ac_xform even if
it is present. If GT.M finds gtm_ac_xform_1 but does not find
gtm_ac_xback_1, it reports a GTM-E-COLLATIONUNDEF error with an additional
mismatch warning GTM-E-COLLFNMISSING.
If the application does not use strings longer than 32,767 bytes, the
alternative collation library need not contain the gtm_ac_xform_1 and
gtm_ac_xback_1 routines. On the other hand, if the application passes
strings greater than 32,767 bytes (but less than the maximum support
string length) and does not provide gtm_xc_xform_1 and gtm_xc_xback_1,
GT.M issues the run-time error GTM-E-COLLARGLONG.
3 Environment_Variable
Environment Variable
GT.M locates the alternative collation sequences through the environment
variable gtm_collate_n where n is an integer from 1 to 255 that identifies
the collation sequence, and pathname identifies the shared library
containing the routines for that collation sequence, for example:
$ gtm_collate_1=/opt/fis-gtm/collation
$ export gtm_collate_1
Multiple alternative collation sequence definitions can co-exist.
4 Establish_Alternative_Collations
Establish Alternative Collations
Alternative collation sequences for a global must be set when the global
contains no data. When the global is defined the collation sequence is
stored in the global. This ensures the future integrity of the global's
collation. If it becomes necessary to change the collation sequence of a
global containing data, you must copy the data to a temporary repository,
modify the variable's collation sequence, and restore the data from the
temporary repository.
Be careful when creating the transformation and inverse transformation
routines. The transformation routine must unambiguously and reliably
encode every possible input value. The inverse routine must faithfully
return the original value in every case. Errors in these routines can
produce delayed symptoms that could be hard to debug. These routines may
not be written in M.
3 Collation_Method
Collation Method
GT.M lets you define an alternative collation sequence as the default when
creating a new database. Subsequently, this default is applied when each
new global is created.
This default collation sequence is set as a GDE qualifier for the ADD,
CHANGE, and TEMPLATE commands using the following syntax:
GDE>CHANGE -REGION DEFAULT -COLLATION_DEFAULT=<0-255>
This qualifier always applies to regions, and takes effect when a database
is created with MUPIP CREATE. The output of GDE SHOW displays this value,
and DSE DUMP -FILEHEADER also includes this information. In the absence of
an alternative default collations sequence, the default used is 0, or
ASCII.
The value cannot be changed once a database file is created, and will be
in effect for the life of the database file. The same restriction applies
to the version of the collation sequence. The version of a collation
sequence implementation is also stored in the database fileheader and
cannot be modified except by recreating the file.
If the code of the collation sequence changes, making it incompatible with
the collation sequence in use when the database was created, use the
following procedure to ensure the continued validity of the database.
MUPIP EXTRACT the database using the older compatible collation routines,
then recreate and MUPIP LOAD using the newer collation routines.
3 Establishing_A_Local_Collation_Sequence
Establishing A Local Collation Sequence
All subscripted local variables for a process must use the same collation
sequence. The collation sequence used by local variables can be
established as a default or in the current process. The local collation
sequence can only be changed when a process has no subscripted local
variables defined.
To establish a default local collation sequence provide a numeric value to
the environment variable gtm_local_collate to select one of the collation
tables, for example:
$ gtm_local_collate=n
$ export gtm_local_collate
where n is the number of a collation sequence that matches a valid
collation number defined by an environment variable in the form
gtm_collate_n.
An active process can use the %LCLCOL utility to define the collation
sequence for subscripts of local variables. %LCLCOL has these extrinsic
entry points:
set^%LCLCOL(n)changes the local collation to the type specified by n.
If the collation sequence is not available, the routine returns a false
(0) and does not modify the local collation sequence.
Example:
IF '$$set^%LCLCOL(3) D
. Write "local collation sequence not changed",! Break
This piece of code illustrates $$set^LCLCOL used as an extrinsic. It would
write an error message and BREAK if the local collation sequence was not
set to 3.
set^%LCLCOL(n,ncol) determines the null collation type to be used with the
collation type n.
With set^%LCLCOL(,ncol), the null collation order can be changed while
keeping the alternate collation order unchanged. If subscripted local
variables exist, null collation order cannot be changed. In this case,
GT.M issues GTM-E-COLLDATAEXISTS.
get^%LCLCOL returns the current local type.
Example:
GTM>Write $$get^%LCLCOL
0
This example uses $$get^%LCLCOL as an extrinsic that returns 0, indicating
that the effective local collation sequence is the standard M collation
sequence.
If set^%LCLCOL is not specified and gtm_local_collate is not defined, or
is invalid, the process uses M standard collation. The following would be
considered invalid values:
* A value less than 0
* A value greater than 255
* A legal collation sequence that is inaccessible to the shared library
Inaccessibility could be caused by a missing environment variable, a
missing image, or by security denial of access.
2 Alternate_Collation
Alternate Collation
Each alternative collation sequence requires a set of four user-created
routines--gtm_ac_xform_1 (or gtm_ac_xform), gtm_ac_xback_1 (or
gtm_ac_xback), gtm_ac_version, and gtm_ac_verify. The original and
transformed strings are passed between GT.M and the user-created routines
using parameters of type gtm_descriptor or gtm32_descriptor. An "include
file" gtm_descript.h, located in the GT.M distribution directory, defines
gtm_descriptor (used with gtm_ac_xform and gtm_ac_xback) as:
typedef struct
{
short len;
short type;
void *val;
} gtm_descriptor;
**Note**
On 64-bit UNIX platforms, gtm_descriptor may grow by up to 8 bytes as a
result of compiler padding to meet platform alignment requirements.
gtm_descriptor is 4 bytes on 32-bit UNIX platforms.
gtm_descript.h defines gtm32_descriptor (used with gtm_xc_xform_1 and
gtm_xc_xback_2) as:
typedef struct
{
unsigned int len;
unsigned int type;
void *val;
} gtm32_descriptor;
where len is the length of the data, type is set to DSC_K_DTYPE_T
(indicating that this is an M string), and val points to the text of the
string.
The interface to each routine is described below.
3 Transformation
Transformation
gtm_ac_xform_1 or gtm_ac_xform routines transforms subscripts to the
alternative collation sequence.>
If the application uses strings use strings longer than 32,767 (but less
than 1,048,576) bytes, the alternative collation library must contain the
gtm_ac_xform_1 and gtm_ac_xback_1 routines. Otherwise, the alternative
collation library should contain gtm_ac_xform and gtm_ac_xback.
The syntax of this routine is:
#include "gtm_descript.h"
int gtm_ac_xform_1(gtm32_descriptor* in, int level, gtm32_descriptor* out, int* outlen);
4 Input_Arguments
Input Arguments
The input arguments for gtm_ac_xform are:
in: a gtm32_descriptor containing the string to be transformed.
level: an integer; this is not used currently, but is reserved for future
facilities.
out: a gtm32_descriptor to be filled with the transformed key.
4 Output_Arguments
Output Arguments
return value: A long word status code.
out: A transformed subscript in the string buffer, passed by
gtm32_descriptor.
outlen: A 32-bit signed integer, passed by reference, returning the actual
length of the transformed key.
The syntax of gtm_ac_xform routine is:
#include "gtm_descript.h"
long gtm_ac_xform(gtm_descriptor *in, int level, gtm_descriptor *out, int *outlen)
5 Input_Arguments
Input Arguments
The input arguments for gtm_ac_xform are:
in: a gtm_descriptor containing the string to be transformed.
level: an integer; this is not used currently, but is reserved for future
facilities.
out: a gtm_descriptor to be filled with the transformed key.
5 Output_Arguments
Output Arguments
The output arguments for gtm_ac_xform are:
return value: a long result providing a status code; it indicates the
success (zero) or failure (non-zero) of the transformation.
out: a gtm_descriptor containing the transformed key.
outlen: an unsigned long, passed by reference, giving the actual length of
the output key.
Example:
#include "gtm_descript.h"
#define MYAPP_SUBSC2LONG 12345678
static unsigned char xform_table[256] =
{
0, 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, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93,
95, 97, 99,101,103,105,107,109,111,113,115,117,118,119,120,121,
122, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
96, 98,100,102,104,106,108,110,112,114,116,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
};
long
gtm_ac_xform (in, level, out, outlen)
gtm_descriptor *in; /* the input string */
int level; /* the subscript level */
gtm_descriptor *out; /* the output buffer */
int *outlen; /* the length of the output string */
{
int n;
unsigned char *cp, *cout;
/* Ensure space in the output buffer for the string. */
n = in->len;
if (n > out->len)
return MYAPP_SUBSC2LONG;
/* There is space, copy the string, transforming, if necessary */
cp = in->val; /* Address of first byte of input string */
cout = out->val; /* Address of first byte of output buffer */
while (n-- > 0)
*cout++ = xform_table[*cp++];
*outlen = in->len;
return 0;
}
3 Inverse_Transformation
Inverse Transformation
This routine returns altered keys to the original subscripts. The syntax
of this routine is:
#include "gtm_descript.h"
long gtm_ac_xback(gtm_descriptor *in, int level, gtm_descriptor *out, int *outlen)
The arguments of gtm_ac_xback are identical to those of gtm_ac_xform.
The syntax of gtm_ac_xback_1 is:
#include "gtm_descript.h"
long gtm_ac_xback_1 ( gtm32_descriptor *src, int level, gtm32_descriptor *dst, int *dstlen)
The arguments of gtm_ac_xback_1 are identical to those of gtm_ac_xform_1.
Example:
#include "gtm_descript.h"
#define MYAPP_SUBSC2LONG 12345678
static unsigned char inverse_table[256] =
{
0, 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, 97, 66, 98, 67, 99, 68,100, 69,101, 70,102, 71,103, 72,
104, 73,105, 74,106, 75,107, 76,108, 77,109, 78,110, 79,111, 80,
112, 81,113, 82,114, 83,115, 84,116, 85,117, 86,118, 87,119, 88,
120, 89,121, 90,122, 91, 92, 93, 94, 95, 96,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
};
long gtm_ac_xback (in, level, out, outlen)
gtm_descriptor *in; /* the input string */
int level; /* the subscript level */
gtm_descriptor *out; /* output buffer */
int *outlen; /* the length of the output string */
{
int n;
unsigned char *cp, *cout;
/* Ensure space in the output buffer for the string. */
n = in->len;
if (n > out->len)
return MYAPP_SUBSC2LONG;
/* There is enough space, copy the string, transforming, if necessary */
cp = in->val; /* Address of first byte of input string */
cout = out->val; /* Address of first byte of output buffer */
while (n-- > 0)
*cout++ = inverse_table[*cp++];
*outlen = in->len;
return 0;
}
3 Version_Control
Version Control
Two user-defined version control routines provide a safety mechanism to
guard against a collation routine being used on the wrong global, or an
attempt being made to modify a collation routine for an existing global.
Either of these situations could cause incorrect collation or damage to
subscripts.
When a global is assigned an alternative collation sequence, GT.M invokes
a user-supplied routine that returns a numeric version identifier for the
set of collation routines, which was stored with the global. The first
time a process accesses the global, GT.M determines the assigned collation
sequence, then invokes another user-supplied routine. The second routine
matches the collation sequence and version identifier assigned to the
global with those of the current set of collation routines.
When you write the code that matches the type and version, you can decide
whether to modify the version identifier and whether to allow support of
globals created using a previous version of the routine.
4 Version_Identifier
Version Identifier
This routine returns an integer identifier between 0 and 255. This integer
provides a mechanism to enforce compatibility as a collation sequence
potentially evolves. When GT.M first uses an alternate collation sequence
for a database or global, it captures the version and if it finds the
version has changed it at some later startup, it generates an error. The
syntax is:
int gtm_ac_version()
Example:
int gtm_ac_version()
{
return 1;
}
4 Verification
Verification
This routine verifies that the type and version associated with a global
are compatible with the active set of routines. Both the type and version
are unsigned characters passed by value. The syntax is:
#include "gtm_descript.h"
int gtm_ac_verify(unsigned char type, unsigned char ver)
Example:
Example:
#include "gtm_descript.h"
#define MYAPP_WRONGVERSION 20406080 /* User condition */
gtm_ac_verify (type, ver)
unsigned char type, ver;
{
if (type == 3)
{
if (ver > 2) /* version checking may be more complex */
{
return 0;
}
}
return MYAPP_WRONGVERSION;
}
3 %GBLDEF
%GBLDEF
Use the %GBLDEF utility to get, set, or kill the collation sequence of a
global variable mapped by the current global directory. %GBLDEF modifies
the collation sequence for neither a global containing data nor a global
whose subscripts span multiple regions. To change the collation sequence
for a global variable that contains data, extract the data, KILL the
variable, change the collation sequence, and reload the data. Use GDE to
modify the collation sequence of a global variable that spans regions.
4 Assigning
Assigning
To assign a collation sequence to an individual global use the extrinsic
entry point:
set^%GBLDEF(gname,nct,act)
where:
* The first argument, gname, is the name of the global. If the global
name appears as a literal, it must be enclosed in quotation marks ("
"). The must be a legal M variable name, including the leading caret
(^).
* The second argument, nct, is an integer that determines whether
numeric subscripts are treated as strings. The value is FALSE (0) if
numeric subscripts are to collate before strings, as in standard M,
and TRUE (1) if numeric subscripts are to be treated as strings (for
example, where 10 collates before 9).
* The third argument, act, is an integer specifying the active collation
sequence from 0, standard M collation, to 255.
**Note**
set^%GBLDEF(gname) returns global specific characteristics, which can
differ from collation characteristics defined for the database file at
MUPIP CREATE time from settings in the global directory. Region collation
may be seen by using the DSE DUMP -FILEHEADER command, implicitly in the
case of M standard collation, as in that case no collation information is
displayed.
If the global contains data, this function returns a FALSE (0) and does
not modify the existing collation sequence definition.
If the global's subscripts span multiple regions, the function returns a
false (0). Use the global directory (GBLNAME object in GDE) to set
collation characteristics for a global whose subscripts span multiple
regions.
Always execute this function outside of a TSTART/TCOMMIT fence. If $TLEVEL
is non-zero, the function returns a false(0).
Example:
GTM>kill ^G
GTM>write $select($$set^%GBLDEF("^G",0,3):"ok",1:"failed")
ok
GTM>
This deletes the global variable ^G, then uses the $$set%GBLDEF as an
extrinsic to set ^G to the collation sequence number 3 with numeric
subscripts collating before strings. Using $$set%GBLDEF as an argument to
$SELECT provides a return value as to whether or not the set was
successful. $SELECT will return a "FAILED" message if the collation
sequence requested is undefined.
4 Examining
Examining
To examine the collation characteristics currently assigned to a global
use the extrinsic entry point:
get^%GBLDEF(gname[,reg])
where gname specifies the global variable name. When gname spans multiple
regions, reg specifies a region in the span.
This function returns the data associated with the global name as a comma
delimited string having the following pieces:
* A truth-valued integer specifying FALSE (0) if numeric subscripts
collate before strings, as in standard M, and TRUE (1) if numeric
subscripts are handled as strings.
* An integer specifying the collation sequence.
* An integer specifying the version, or revision level, of the currently
implemented collation sequence.
**Note**
A "0" return from $$get^%gbldef(gname[,reg]) indicates that the global has
no special characteristics and uses the region default collation, while a
"0,0,0" return indicates that the global is explicitly defined to M
collation.
Example:
GTM>Write $$get^%GBLDEF("^G")
1,3,1
This example returns the collation sequence information currently assigned
to the global ^G.
4 Deleting
Deleting
To delete the collation characteristics currently assigned to a global,
use the extrinsic entry point:
kill^%GBLDEF(gname)
o If the global contains data, the function returns a false (0) and does
not modify the global.
o If the global's subscript span multiple regions, the function returns
a false (0). Use the global directory (GBLNAME object in GDE) to set
collation characteristics for a global whose subscripts span multiple
regions.
o Always execute this function outside of a TSTART/TCOMMIT fence. If
$TLEVEL is non-zero, the function returns a false (0).
2 Matching_Alternative_Patterns
Matching Alternative Patterns
GT.M allows the definition of unique patterns for use with the pattern
match operator, in place of, or in addition to, the standard C, N, U, L,
and P. You can redefine existing pattern codes (patcodes), or add new
ones. These codes are defined in a specification file. The format is
described in the next section.
3 Pattern_Code_Definition
Pattern Code Definition
This section explains the requirements for specifying alternative pattern
codes. These specifications are created as a table in a file which GT.M
loads at run time.
Use the following keywords to construct your text file. Each keyword must:
* Appear as the first non-whitespace entry on a line.
* Be upper case.
The table names also must be uppercase. The patcodes are not
case-sensitive.
PATSTART indicates the beginning of the definition text and must appear
before the first table definition.
PATTABLE indicates the beginning of the table definition. The keyword
PATTABLE is followed by whitespace, then the table name. The text file can
contain multiple PATTABLEs.
PATCODE indicates the beginning of a patcode definition. The keyword
PATCODE is followed by whitespace, then the patcode identifying character.
On the next line enter a comma-delimited list of integer codes that
satisfy the patcode. A PATCODE definition is always included in the most
recently named PATTABLE. A PATTABLE can contain multiple PATCODEs.
PATEND indicates the end of the definition text; it must appear after the
last table definition.
To continue the comma-delimited list on multiple lines, place a dash (-)
at the end of each line that is not the last one in the sequence. To enter
comments in the file, begin the line with a semi-colon (;).
The following example illustrates a possible patcode table called
"NEWLANGUAGE," The example has definitions for patcodes "S," which would
be a non-standard pattern character, and "L," which would substitute
alternative definitions for the standard "L" (or lower case) pattern
characters.
Example:
PATSTART
PATTABLE NEWLANGUAGE
PATCODE S
144,145,146,147,148,149,150
PATCODE L
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
PATEND
Be mindful of the following items as you define your patcode table.
* A table name can only be loaded once during an invocation of GT.M. It
cannot be edited and reloaded, while the M process is running.
* The table name "M" is a reserved designation for standard M, which is
included in the GT.M run-time library.
* Standard patcodes A and E cannot be explicitly redefined.
A is always the union of codes U and L; E always designates the set of
all characters.
* The C pattern code you define is used by GT.M to determine those
characters which are to be treated as unprintable.
* In UTF-8 mode, M standard patcodes (A,C,L,U,N,P,E) work with Unicode
characters. Application developers can neither change their default
classification nor define the non-standard patcodes
((B,D,F-K,M,O,Q-T,V-X) beyond the ASCII subset. This means that the
pattern tables cannot contain characters with codes greater than the
maximum ASCII code 127.
All characters not defined as C are treated as printable.
3 Code_Selection
Code Selection
To establish a default patcode table for a database define the environment
variable:
$ gtm_pattern_file=pathname
$ export gtm_pattern_file
where filename is the text file containing the patcode table definition,
and
$ gtm_pattern_table=tablename
$ export gtm_pattern_table
where tablename is the name of the patcode table within the file pointed
to by gtm_pattern_file.
Within an active process, the patcode table is established using the M
VIEW command and the %PATCODE utility. Before invoking the %PATCODE
utility, you may use VIEW to load pattern definition files for GT.M. The
required keyword and value are:
VIEW "PATLOAD":"pathname"
This allows you to use the %PATCODE utility or the VIEW command to set
current patcode table. The format of the VIEW command to set the patcode
table is:
VIEW "PATCODE":"tablename"
This is equivalent to set ^%PATCODE explained below.
%PATCODE has the following extrinsic entry points:
set^%PATCODE(tn)
sets the current patcode table to the one having the name specified by tn,
in the defined file specification.
Example:
GTM>Write $$set^%PATCODE("NEWLANGUAGE")
1
If there is no table with that name, the function returns a false (0) and
does not modify the current patcode table.
get^%PATCODE
returns the current patcode table name.
Example:
GTM>Write $$get^%PATCODE
NEWLANGUAGE
1 Err_Processing
Err Processing
This chapter describes GT.M features and techniques for handling errors.
Errors in programs may be classified as "predictable" meaning foreseen, or
"unpredictable" meaning unforeseen.
M programs may attempt to recover from predictable errors. Device errors
that can be remedied by an operator are the most common class of errors
for which recovery provides a large benefit. Predictable errors from which
the program does not attempt to recover are generally treated the same as
unpredictable errors.
A typical application handles unpredictable errors by logging as much
information about the error as the designer considers useful, then
terminating or restarting the application from a known point.
Because GT.M invokes error handling when things are not normal, careful
design and implementation of error handling are required to minimize the
impact of errors and the cost of subsequent prevention.
The GT.M compiler detects and reports syntax errors at:
* Compile time while producing the object module from a source file.
* Run time while compiling code for M indirection and XECUTEs.
* Run time when the user is working in Direct Mode.
The GT.M run-time system:
* Recognizes and reports execution errors when they occur.
* Reports errors flagged by the compiler when they fall in the execution
path.
2 Compile_Time
Compile Time
To understand the compile-time error message format, consider this
incorrect source line:
S =B+C
If this were line 7 of a source file ADD2.m, the compiler reports the
compile-time error with the message:
S =B+C ^-----
At column 4, line 7, source module ADD2
Variable expected in this context
The compile-time error message format consists of three lines. The first
two lines tell you the line and location where the error occurred. The
last line describes the M syntax error. If you requested a listing file,
it contains the same information and looks as follows:
.
.
6 . . .
7 S =B+C
^-----
Variable expected in this context
8 . . .
.
.
2 Process_Compile_Errors
Process Compile Errors
At compile-time, the compiler stops processing a routine line as soon as
it detects the first error on that line. By default, the compiler displays
the line in error on stderr , and also in a listing file when the compiler
options include -list. By default, the compiler processes the remaining
source lines until it exceeds the maximum error count of 127.
The compile-time error message format displays the line containing the
error and the location of the error on the line. The error message also
indicates what was incorrect about the M statement. For more information
on the error message format, refer to the GT.M Message and Recovery
Procedures Reference Manual.
You may correct compile-time errors immediately by activating an editor
and entering the correct syntax in the source program. Because several
errors may occur on a line, examine the line carefully to avoid compiling
the routine several times.
The MUMPS command qualifier -ignore, which is the default, instructs GT.M
to produce an object file even if the compiler detects errors in the
source code. As long as the execution path does not encounter the
compile-time errors, the GT.M run-time system executes the
compiled-as-written routine. You may take advantage of this feature to
exercise some parts of your program before correcting errors detected by
the compiler.
2 Run-time_Error
Run-time Error
To understand the run-time error message format, consider this short
program printsum.m:
SET A=17
GO SET B=21
WRITE A+C
When you try to execute this program, the last statement causes an error
since the variable C is undefined. If $ETRAP="B", GT.M displays the
run-time error message:
$ mumps -run printsum
%GTM-E-UNDEF, Undefined local variable: C
At MUMPS source location GO+1^printsum
GTM>
GT.M informs you of the error (Undefined local variable) and where in the
routine the error occurred (GO+1). Note that the run-time system displays
the GTM> prompt, indicating that the process has entered Direct Mode. GT.M
places run time error information in the intrinsic Special Variable $ECODE
and $ZSTATUS.
Compile-time error messages may appear at run time. This is because errors
in indirection and the compile-as-written feature leave errors that are
subsequently reported at run time.
The GT.M utilities use portions of the run-time system and therefore may
issue run-time errors as well as their own unique errors.
2 Processing_Run-time
Processing Run-time
GT.M does not detect certain types of errors associated with indirection,
the functioning of I/O devices, and program logic until run-time. Also,
the compile-as-written feature may leave errors which GT.M reports at
run-time when it encounters them in the execution path. At run-time, GT.M
reports any error encountered to stderr. The run-time system suspends
normal execution of the routine as soon as it detects an error.
GT.M responds to errors differently depending on whether it encounters
them in Direct Mode (at the command line) or during normal program
execution.
When an executing GT.M image encounters an error:
* if Direct Mode is active at the top of the invocation stack, GT.M
stays in Direct Mode.
* otherwise, if the error comes from a device that has an EXCEPTION,
GT.M executes the EXCEPTION string.
* otherwise, if $ETRAP'="" GT.M transfers control to the code defined by
$ETRAP as if it had been inserted at the point of the error, unless
$ECODE'="", in which case it executes a TROLLBACK:$TLEVEL followed by
a QUIT:$QUIT "" QUIT.
* otherwise, if $ZTRAP'="" GT.M executes $ZTRAP.
* otherwise, GT.M performs a QUIT:$QUIT "" QUIT and reissues the error
at the new stack level, if no other error traps ($ETRAP or $ZTRAP) are
uncovered by decending the stack, GT.M reports the error on the
principal device and terminates the image.
After the action, if any, invoked by $ETRAP, $ZTRAP or EXCEPTION:
* if the process ends in Direct Mode - as a result either of performing
a BREAK in the executed string or of starting in Direct Mode - GT.M
reports the error on the principal device.
* otherwise, if the executed string contains an unstacked transfer of
control, the only implicit behavior is that as long as $ECODE'="" and
$ZTRAP'="" an attempt to QUIT from the level of the current error
causes that error to be reissued at the new stack level.
* otherwise, if $ETRAP'="" GT.M performs a QUIT$QUIT "" QUIT and
reissues the error at the new stack level.
* otherwise, $ZTRAP must contain code and GT.M retries the line of M on
which the error occurred.
3 Direct_Mode
Direct Mode
When GT.M detects an error in Direct Mode, it reports the error with a
message and leaves the process at the GTM> prompt.
Example:
GTM>ZW
ZW
^_____
%GTM-E-INVCMD, Invalid command keyword encountered
GTM>
In Direct Mode, GT.M provides access to the RECALL command. RECALL allows
you to retrieve a Direct Mode command line with a minimum of typing. A
GT.M line editor allows you to make quick changes or corrections to the
command line.
3 Run-time_Errors_Outside_of_Direct_Mode
Run-time Errors Outside of Direct Mode
If GT.M encounters an error outside of code entered in Direct Mode, GT.M
executes the $ETRAP or $ZTRAP special variable, if either of them have a
length greater than zero, which only one can have at a given point in
time.
The $ETRAP and $ZTRAP special variables specifiy an action that GT.M
should perform when an error occurs during routine execution. $ETRAP and
$ZTRAP can establish one or more error handling "actions".
**Note**
The environment variable gtm_etrap specifies an initial value of $ETRAP to
override the default value of "B" for $ZTRAP as the base level error
handler. The gtmprofile script sets gtm_etrap to "Write:(0=$STACK) ""Error
occurred: "",$ZStatus,!" which you can customize to suit your needs. For
more information, refer to "Processing Errors".
2 Program_Handling_of_Errors
Program Handling of Errors
GT.M provides the error handling facilities described in the M standard.
In addition, GT.M provides a number of extensions for error handling. Both
are discussed in the following sections. The following table summarizes
some of the tools, which are then described in more detail within the
context of various techniques and examples.
+------------------------------------------------------------------------+
| Summary of GT.M Error-Handling Facilities |
|------------------------------------------------------------------------|
| EXTENSION | EXPLANATION |
|--------------------------+---------------------------------------------|
| | Provides a deviceparameter specifying an |
| OPEN/USE/CLOSE EXCEPTION | XECUTE string or entryref that GT.M invokes |
| | upon encountering a device-related |
| | exception condition. |
|--------------------------+---------------------------------------------|
| | Creates a listing file of all the errors |
| MUMPS -list ZLINK | detected by the compiler. Detects syntax |
| :"-list" | errors. Useful in the process of re-editing |
| | program to correct errors. |
|--------------------------+---------------------------------------------|
| ZGoto | Provides for removing multiple levels from |
| | the M invocation stack. |
|--------------------------+---------------------------------------------|
| ZMESSAGE | Creates or emulates arbitrary errors. |
|--------------------------+---------------------------------------------|
| $STACK | Contains the current level of M execution |
| | stack depth. |
|--------------------------+---------------------------------------------|
| $STACK() | Returns values describing aspects of the |
| | execution environment. |
|--------------------------+---------------------------------------------|
| | Contains a list of error codes for "active" |
| $ECODE | errors; these are the errors that have |
| | occurred, but have not yet been cleared. |
|--------------------------+---------------------------------------------|
| | Contains an integer count of M virtual |
| $ESTACK | machine stack levels that have been |
| | activated and not removed, since the last |
| | time $ESTACK was NEW'd. |
|--------------------------+---------------------------------------------|
| | Contains a string value that GT.M invokes |
| $ETRAP | when an error occurs during routine |
| | execution. |
|--------------------------+---------------------------------------------|
| | Indicates whether the current block of code |
| $QUIT | was called as an extrinsic function or a |
| | subroutine. |
|--------------------------+---------------------------------------------|
| | Holds the value of the status code for the |
| $ZCSTATUS | last compilation performed by a ZCOMPILE |
| | command. |
|--------------------------+---------------------------------------------|
| | Holds the value of the status code for the |
| $ZEDIT | last edit session invoked by a ZEDIT |
| | command. |
|--------------------------+---------------------------------------------|
| | Holds the value '1' (TRUE) if the last READ |
| $ZEOF | on the current device reached end-of-file, |
| | otherwise holds a '0' (FALSE). |
|--------------------------+---------------------------------------------|
| | Contains a string supplied by the |
| $ZERROR | application, typically one generated by the |
| | code specified in $ZYERROR. |
|--------------------------+---------------------------------------------|
| $ZLEVEL | Contains current level of DO/EXECUTE |
| | nesting ($STACK+1). |
|--------------------------+---------------------------------------------|
| $ZMESSAGE() | Translates a UNIX/GT.M condition code into |
| | text form. |
|--------------------------+---------------------------------------------|
| | Contains the error condition code and |
| $ZSTATUS | location of last exception condition |
| | occurring during routine execution. |
|--------------------------+---------------------------------------------|
| | Contains an XECUTE string or entryref that |
| $ZTRAP | GT.M invokes upon encountering an exception |
| | condition. |
|--------------------------+---------------------------------------------|
| | Contains an entryref to invoke when an |
| $ZYERROR | error occurs; typically used to maintain |
| | $ZERROR. |
+------------------------------------------------------------------------+
3 $ECODE
$ECODE
The value of $ECODE is a string that may reflect multiple error
conditions. As long as no error has occured, the value of $ECODE is equal
to the empty string.
$ECODE contains a list of errors codes for "active" errors - the error
conditions which are not yet resolved. If there are no active errors,
$ECODE contains the empty string. The value of $ECODE can be SET.
The most recent error in $ECODE appears first, the oldest last. If the
error is defined by the M standard, the code starts with an "M", GT.M
error codes including those provided by OS services start with "Z", and
application defined codes must start with "U". Every code is separated by
a coma (,) and there is always a coma at the beginning and at the end of a
list. GT.M provided codes are those reported in $ZSTATUS, interpreted by
$ZMESSAGE() and recognized as arguments to ZMESSAGE command. When GT.M
supplies a standard error code in $ECODE, it also supplies a corresponding
'Z' code.
Example (setting $ECODE):
SET $ECODE="" ;sets $ECODE to the empty string
SET $ECODE=",M20," ;an ANSI M standardized error code
SET $ECODE=",U14," ;user defined error code
SET $PIECE($ECODE,",",2)="Z3," ;insert a non-ANSI error code
SET $PIECE($ECODE,",",$LENGTH($ECODE,",")+1)="An..," ;append
Standard Error processing affects the flow of control in the following
manner. Detection of an error causes GOTO implicit sub-routine. When
$ECODE="", the implicit subroutine is $ETRAP and QUIT:$QUIT "" QUIT.
Otherwise the implicit subroutine is $ETRAP followed by TROLLBACK:$TLEVEL
and then QUIT:$QUIT "" QUIT.
The QUIT command behaves in a special fashion while the value of $ECODE is
non-empty. If a QUIT command is executed that returns control to a less
nested level than the one where the error occurred, and the value of
$ECODE is still non-empty, first all normal activity related to the QUIT
command occurs (especially the unstacking of NEWed variables) and then the
current value of $ETRAP is executed. Note that, if $ETRAP had been NEWed
at the current or intervening level, the unstacked value of $ETRAP is
executed.
SETting $ECODE to an invalid value is an error. SETting $ECODE to a valid
error behaves like detection of error. SETting $ECODE="" does not cause a
change in the flow, but effects $STACK(), subsequent $QUITs and errors.
**Note**
To force execution of an error trap or to flag a user-defined error ("U"
errors), make the value of $ECODE non-empty:
SET $ECODE=",U13-User defined error trap,"
**Note**
The value of $ECODE provides information about errors that have occurred
since the last time it was reset to an empty string. In addition to the
information in this variable, more detailed information can be obtained
from the intrinsic function $STACK. .
3 $ZSTATUS_Content
$ZSTATUS Content
$ZSTATUS contains a string value specifying the error condition code and
location of the last exception condition that occurred during routine
execution.
3 $ZERROR_and_$ZYERROR
$ZERROR and $ZYERROR
After an error occurs, if $ZYERROR is set to a valid entryref that exists
in the current environment, GT.M invokes the routine at that entryref with
an implicit DO before returning control to M code specified by $ZTRAP or
device EXCEPTION. It is intended that the code invoked by $ZYERROR use the
value of $ZSTATUS to select or construct a value to which it SETs $ZERROR.
If $ZYERROR is empty, $ZYERROR="unprocessed $ZERROR, see $ZSTATUS".
If there is a problem with the content of $ZYERROR or if the execution of
the code it invokes, GT.M sets $ZERROR=$ZSTATUS for the secondary error
and terminates the attempt to use $ZYERROR. During code evoked by
$ZYERROR, the value of $ZERROR is the empty string.
3 $ETRAP_Behavior
$ETRAP Behavior
If, at the time of any error, the value of $ETRAP is non-empty, GT.M
proceeds as if the next instruction to be excuted were the first one on
"the next line" and the code on that next line would be the same as the
text in the value of $ETRAP. Furthermore, GT.M behaves as if the line
following "the next line" looks like:
QUIT:$QUIT "" QUIT
When a value is assigned to $ETRAP, the new value replaces the previous
value. The value of $ZTRAP becomes equal to the empty string without being
stacked.
3 Nesting_$ETRAP_and_using_$ESTACK
Nesting $ETRAP and using $ESTACK
When you need to set up a stratified scheme where one level of subroutines
use one error trap setting and another more nested subroutine uses a
different one; the more nested subroutine must NEW $ETRAP. When $ETRAP is
NEWed, its old value is saved and copied to the current value. A
subsequent SET $ETRAP=<new-value> then establishes the error trapping code
for the current execution level.
The QUIT command that reverts to the calling routine causes the NEWed
values to be unstacked, including the one for $ETRAP.
If an error occurs while executing at the current execution level (or at
an execution level farther from the initial base stack frame), the code
from the current $ETRAP gets executed. Unless there is a GOTO or ZGOTO,
when the execution of that code is complete, control reverts to the
implicit QUIT command that returns to the calling routine. At this time,
any prior value of $ETRAP is reinstated.
While at the more nested execution level(s), if an error occurs, the code
from the current $ETRAP is executed. After the QUIT to a less nested
level, the code from the current $ETRAP gets executed. The current $ETRAP
may be different from the $ETRAP at the time of the error due to
unstacking. This behavior continues until one of the following possible
situations occur:
* $ECODE is empty. When the value of $ECODE is equal to the empty
string, error processing is no longer active, and normal processing
resumes.
* An execution level is reached where the value of $ETRAP is empty
($ZTRAP might be non-empty at that level). When the values of both
$ZTRAP and $ETRAP are equal to the empty string, no error trapping is
active and the process repeats.
* The stack is reduced to an empty state. When there is no previous
level left to QUIT into, GT.M returns to the operating system level
shell. A frame that is in direct mode stops the process by putting the
user back into the Direct Mode shell.
When dealing with stratified error trapping, it is important to be aware
of two additional intrinsic variables: $STACK and $ESTACK. The values of
both of these variables indicate the current execution level. The value of
$STACK is an "absolute" value that counts from the start of the GT.M
process, whereas the value of $ESTACK restarts at zero (0) each time
$ESTACK is NEWed.
It is often beneficial to NEW both $ETRAP and $ESTACK a the same time.
3 Behavior
Behavior
If, at the time of any error, the value of $ZTRAP is non-empty, GT.M uses
the $ZTRAP contents to direct execution of the next action.
By default, execution proceeds as if the next instruction to be executed
were the first one on "the next line", and the code on that next line
would be the same as the text in the value of $ZTRAP. Unless there is a
GOTO or ZGOTO, after the code in $ZTRAP has been executed, GT.M attempts
to execute the line with the error again. When a value is assigned to
$ZTRAP, the new value replaces the previous value. If the value of $ETRAP
is a non-empty one, $ETRAP is implicitly NEWed, and the value of $ETRAP
becomes equal to the empty string; this ensures that at most one of $ETRAP
and $ZTRAP is not the empty string. If the environment variable
gtm_ztrap_new evaluates to boolean TRUE (case insensitive string "TRUE",
or case insensitive string "YES", or a non-zero number), $ZTRAP is NEWed
when $ZTRAP is SET; otherwise $ZTRAP is not stacked when it is SET.
Other than the default behavior, $ZTRAP settings are controlled by the
environment variable gtm_ztrap_form as described in the following table.
+------------------------------------------------------------------------+
| gtm_ztrap_form | $ZTRAP and EXCEPTION Behavior |
|----------------+-------------------------------------------------------|
| | Content is code executed after the error; in the |
| code | absence of GOTO, ZGOTO, or QUIT, execution resumes at |
| | the beginnig of the line containing the error - |
| | default behavior |
|----------------+-------------------------------------------------------|
| entryref | Content is an entryref to which control is |
| | transferred by an implicit GOTO |
|----------------+-------------------------------------------------------|
| adaptive | If content is valid code treat it as described for |
| | "code", otherwise attempt to treat it as an entryref |
|----------------+-------------------------------------------------------|
| | Content is entryref - remove M virtual stack levels |
| popentryref | until the level at which $ZTRAP was SET, then GOTO |
| | the entryref; the stack manipulation occurs only for |
| | $ZTRAP and not for EXCEPTION |
|----------------+-------------------------------------------------------|
| | If content is valid code treat it as described for |
| popadaptive | code, otherwise attempt to treat it as an entryref |
| | used as described for popentryref |
+------------------------------------------------------------------------+
Although the "adaptive" and "popadaptive" behaviors permit mixing of two
behaviors based on the current value of $ZTRAP, the $ZTRAP behavior type
is selected at process startup from gtm_ztrap_form and cannot be modified
during the life of the process.
Note
Like $ZTRAP values, invocation of device EXCEPTION values follow the
pattern specified by the current gtm_ztrap_form setting.
3 $ETRAP_and_$ZTRAP
$ETRAP and $ZTRAP
The activation of $ETRAP and $ZTRAP are the same, however there are a
number of differences in their subsequent behavior.
For subsequent errors the then current $ZTRAP is invoked, while with
$ETRAP, behavior is controlled by the state of $ECODE. This means that
when using $ZTRAP, it is important to change $ZTRAP, possibly to the empty
string, at the beginning of the action in order to protect against
recursion caused by any errors in $ZTRAP itself or in the code it invokes.
If there is no explicit or implicit GOTO or ZGOTO in the action, once a
$ZTRAP action completes, execution resumes at the beginning of the line
where the error occurred, while once a $ETRAP action completes, there is
an implicit QUIT. This means that $ZTRAP actions that are not intended to
permit a successful retry of the failing code should contain a GOTO, or
more typically a ZGOTO. In contrast, $ETRAP actions that are intended to
cause a retry must explicitly reinvoke the code where the error occurred.
For QUITs from the level at which an error occurred, $ZTRAP has no effect,
where $ETRAP behavior is controlled by the state of $ECODE. This means
that to invoke an error handler nested at the lower level, $ZTRAP actions
need to use an explicit ZMESSAGE command, while $ETRAP does such
invocations implicitly unless $ECODE is SET to the empty string.
3 $ZTRAP_With_$ETRAP
$ZTRAP With $ETRAP
It is important to be aware of which of the trap mechanisms is in place to
avoid unintended interactions, and aware of which conditions may cause a
switch-over from one mode of error handling to the other.
Whenever a SET command is executed that assigns a value to either $ZTRAP
or $ETRAP, the value of the other error handling variable is examined. If
the other value is non-empty, an implicit NEW command is executed that
saves the current value of that variable, and then the value of that
variable is set to the empty string. After this, the requested assignment
is made effective.
For example, re-setting $ETRAP is internally processed as:
NEW:$LENGTH($ZTRAP) $ZTRAP SET $ETRAP=code
Whereas, SET $ZTRAP=value is internally processed as:
NEW:$LENGTH($ETRAP) $ETRAP SET $ZTRAP=value
Note that NEW of $ETRAP or $ZTRAP implicitly sets the value of the empty
string after saving the prior value. As a result, at most one of the two
error handling machanisms can be effective at any given point in time.
If an error handling procedure was invoked through the $ETRAP method, and
the value of $ECODE is non-empty when QUITing from the level of which the
error occurred, the behavior is to transfer control to the error handler
associated with the newly unstacked level. However, if the QUIT command at
the end of error level happens to unstack a saved value of $ZTRAP (and
thus cause the value of $ETRAP to become empty), the error handling
mechanism switches from $ETRAP-based to $ZTRAP-based.
**Note**
At the end of an error handling procedure invoked through $ZTRAP, the
value of $ECODE is not examined, and this value (if any) does not cause
any transfer to another error handling procedure. However, if not cleared
it may later trigger a $ETRAP unstacked by a QUIT.
3 $ETRAP_or_$ZTRAP
$ETRAP or $ZTRAP
Making a choice between the two mechanisms for error handling is mostly a
matter of compatibility. If compatibility with existing GT.M code is
important, and that code happens to use $ZTRAP, then $ZTRAP is the best
effort choice. If compatibility with code written in MUMPS dialects from
other vendors is important, then $ETRAP or a non-default form of $ZTRAP
probably is the better choice.
When no pre-existing code exists that favors one mechanism, the features
of the mechanisms themselves should be examined.
Almost any effect that can be achieved using one mechanism can also be
achieved using the other. However, some effects are easier to achieve
using one method, and some are easier using with the other.
If the mechanisms are mixed, or there is a desire to refer to $ECODE in an
environment using $ZTRAP, it is recommended to have $ZTRAP error code SET
$ECODE="" at some appropriate time, so that $ECODE does not become
cluttered with errors that have been successfully handled.
**Note**
A device EXCEPTION gets control after a non-fatal device error and
$ETRAP/$ZTRAP get control after other non-fatal errors.
3 IO_Errors
IO Errors
When GT.M encounters an error in the operation of an I/O device, GT.M
executes the EXCEPTION deviceparameter for the OPEN/USE/CLOSE commands. An
EXCEPTION deviceparameter specifies an action to take when an error occurs
in the operation of an I/O device. The form of the EXCEPTION action is
subject to the gtm_ztrap_form setting described for $ZTRAP, except that
there is never any implicit popping with EXCEPTION actions. If a device
has no current EXCEPTION, GT.M uses $ETRAP or $ZTRAP to handle an error
from that device.
GT.M provides the option to:
* Trap or process an exception based on device error.
* Trap or process an exception based on terminal input.
An EXCEPTION based on an error for the device applies only to that device,
and provides a specific error handler for a specific I/O device.
The CTRAP deviceparameter for USE establishes a set of trap characters for
terminal input. When GT.M encounters an input character in that set, GT.M
executes the EXCEPTION deviceparamenter, or, $ETRAP or $ZTRAP if the
device has no current EXCEPTION.
Example:
GTM>ZPRINT ^EP12
EP12 WRITE !,"THIS IS ",$TEXT(+0)
SET $ECODE="";this only affects $ETRAP
SET $ETRAP="GOTO ET"
;N $ZT S $ZT="W !,"CAN'T TAKE RECIPROCAL OF 0"",*7"
USE $P:(EXCEPTION="D BYE":CTRAP=$C(3))
WRITE !,"TYPE <CTRL-C> TO STOP"
LOOP FOR DO
. READ !,"TYPE A NUMBER: ",X
. WRITE ?20,"HAS RECIPROCAL OF: ",1/X
. QUIT
ET . WRITE !,"CAN'T TAKE RECIRPOCAL OF 0",*7
. SET $ECODE=""
QUIT
BYE WRITE !,"YOU TYPED <CTRL-C> YOU MUST BE DONE!"
USE $P:(EXCEPTION="":CTRAP="")
WRITE !,"$ZSTATUS=",$ZSTATUS
ZGOTO 1
GTM>DO ^EP12
THIS IS EP12
TYPE <CTRL-C> TO STOP
TYPE A NUMBER: 1 HAS RECIPROCAL OF: 1
TYPE A NUMBER: 2 HAS RECIRPOCAL OF: .5
TYPE A NUMBER: 3 HAS RECIPROCAL OF: .33333333333333
TYPE A NUMBER: 4 HAS RECIPROCAL OF: .25
TYPE A NUMBER: HAS RECIPROCAL OF:
CAN'T TAKE RECIPROCAL OF 0
TYPE A NUMBER:
YOU TYPED <CTRL-C> YOU MUST BE DONE!
$ZSTATUS=150372498,LOOP+1^EP12,%GTM-E-CTRAP,Character trap $C(3) encountered
GTM>
This routine prompts the user to enter a number at the terminal. If the
user enters a zero, GT.M encounters an error and executes $ETRAP (or
$ZTRAP). The action specified reports the error and returns to prompt the
user to enter a number. With $ZTRAP, this is very straightforward. With
$ETRAP, some care is required to get the code to resume at the proper
place. The CTRAP deviceparameter establishes <CTRL-C> as a trap character.
When GT.M encounters a <CTRL-C>, GT.M executes the EXCEPTION string whcih
transfers control to the label BYE. At the label BYE, the routine
terminates execution with an error message. Using the EXCEPTION
deviceparameter with CTRAP generally simplifies $ETRAP or $ZTRAP handling.
$ZSTATUS allows the routine to find out which trap character GT.M
encountered. When a routine has several character traps set, $ZSTATUS
provides useful information for identifying which character triggered the
trap, and thereby allows a custom response to a specific input.
1 Triggers
Triggers
2 Trigger_Definition
Trigger Definition
A trigger definition file is a text file used for adding new triggers,
modifying existing triggers, or removing obsolete triggers. A trigger
definition file consists of one or more trigger definitions. A trigger
definition includes the following information:
* Trigger signature: A trigger signature consists of global variable,
subscripts, value, command, and trigger code. GT.M uses a combination
of global variable, subscripts, value, and command to find the
matching trigger to invoke for a database update.
1. Global Variable: The name of a specific global to which this
trigger applies.
2. Subscripts: Subscripts for global variable nodes of the named
global, specified using the same patterns as the ZWRITE command.
3. Value: For commands that SET or update the value at a node, GT.M
honors an optional pattern to screen for changes to delimited
parts of the value. A value pattern includes a piece separator
and a list of pieces of interest.
4. Command: There are four commands: SET, KILL, ZTRIGGER, and ZKILL
(ZWITHDRAW is identical to ZKILL) the shorter name for the
command is used when specifying triggers. MERGE is logically
treated as equivalent to a series of SET operations performed in
a loop. GT.M handles $INCREMENT() of a global matching a SET
trigger definition as a triggering update.
5. Trigger code: A string containing M code that GT.M executes when
application code updates, including deletions by KILL and like
commands, a global node with a matching trigger. The specified
code can invoke additional routines and subroutines.
**Note**
While GT.M does not restrict trigger code from performing I/O
operations, FIS recommends against using OPEN, USE, READ, WRITE
and CLOSE within trigger application code. Such operations may be
useful for development and diagnostic purposes. However, triggers
implicitly run as TP transactions and I/O violates the ACID
property of Isolation. In addition, MUPIP has somewhat different
I/O handling characteristics than the main GT.M run-time, so I/O
within triggers run by MUPIP may behave differently than within
the originating application environment.
* ACID property modifiers for triggered database updates: Currently,
GT.M merely performs a syntax check on this part of a trigger
definition. GT.M ensures the triggering database update, and any
updates generated by trigger logic executed with transaction
semantics. With the VIEW "NOISOLATION" command, GT.M transaction
processing has long provided a mechanism for an application to inform
the GT.M runtime system that it need not enforce Isolation. In such a
case, the application and schema design provides Isolation by ensuring
only one process ever updates nodes in a particular global at any
given time, say by using $JOB as a subscript. This property
anticipates a time when a trigger specification can provide
NOISOLATION for particular nodes, in contrast to entire globals, and
for every update to that node, in contrast to by process use of a VIEW
command. Currently, the GT.M runtime system enforces Consistency for
application logic inside a transaction and for triggered updates. This
property anticipates a time when a trigger specification permits an
application to inform the runtime system the application and schema
design ensures appropriate Consistency for a trigger and its logic,
thus relieving the GT.M runtime system from that task.
* Trigger Name: You can optionally specify a trigger name that uniquely
identifies each trigger. GT.M uses a trigger name for error reporting
and configuration management of triggers - for example, a ZSHOW "S"
reports the name of each trigger on the stack. If you do not specify a
trigger name, GT.M automatically generates one using the global name
as a base. Both user-specified trigger name and automatically
generated trigger names occupy different name space and last for the
life of the definition. A user-specified trigger name is an
alphanumeric string of up to 28 characters. It must start with an
alphabetic character or a percent sign (%). For a trigger name, GT.M
uses the same naming convention as an M name. In other contexts, GT.M
truncates M names at 31 characters. However, GT.M treats a trigger
name of over 28 characters as an error. This is because a trigger name
uniquely identifies a trigger and truncation may cause duplication.
An automatically generated trigger name is a string comprised of two
parts. Using the global name as a base, GT.M takes the first part as an
alphanumeric string of up to 21 characters starting with an alphabetic
character or a percent sign (%). The trailing part consists of an
automatically incremented number in the form of #n# where n is a whole
number that monotonically increases from 1 to 999999 that uniquely
identifies a trigger for the same update. For example, if no trigger names
are specified in the trigger definition file, GT.M automatically generates
trigger names Account#1#, Account#2#, and Account#3# for the first three
triggers defined for global variable ^Account. An attempt to use automatic
assignment for more than a million triggers produces an error. Once the
numeric portion of the auto generated names reaches 999999, you must
reload all triggers associated with the global variables that use the auto
generated name space. At run-time GT.M generates a trailing suffix of a
hash-sign (#) followed by up to two characters to ensure that every
trigger has a unique designation, even when the environment is complex.
The run-time suffix applies to both user-specified and automatically
generated trigger names. It helps in differentiating triggers in different
database files with the same name.
To apply this trigger definition file to GT.M, all you do is to load it
using MUPIP TRIGGER -TRIGGERFILE or $ZTRIGGER(). GT.M would invoke trigger
name TrigAcct on every SET operation on ^Acct("ID"). Internally, GT.M
stores trigger TrigAcct in the same database file where ^Acct is stored.
The syntax of an entry in a trigger definition file is:
{-triggername|-triggername-prefix*|-*|{+|-}trigvn -commands=cmd[,...]
-xecute=strlit1 [-[z]delim=expr][-pieces=[lvn=]int1[:int2][;...]]
[-options={[no]i[solation]|[no]c[onsistencycheck]}...] [-name=strlit2]}
2 Semantics
Semantics
GT.M stores Triggers for each global variable in the database file for
that global variable. When a global directory maps a global variable to
its database file, it also maps triggers for that global variable to the
same database file. When an extended reference uses a different global
directory to map a global variable to a database file, that global
directory also maps triggers for that global variable to that same
database file.
Although triggers for SET and KILL / ZKILL commands can be specified
together, the command invoking a trigger is always unique. The ISV
$ZTRIGGEROP provides the trigger code which matched the triggering
command.
Whenever a command updates a global variable, the GT.M runtime system
first determines whether there are any triggers for that global variable.
If there are any triggers, it scans the signatures for subscripts and node
values to identify matching triggers. If multiple triggers match, GT.M
invokes them in an arbitrary order. Since a future version of GT.M,
potentially multi-threaded, may well choose to execute multiple triggers
in parallel, you should ensure that when a node has multiple triggers,
they are coded so that correct application behavior does not rely on the
order in which they execute.
When a process executes a KILL, ZKILL or SET command, the target is the
global variable node specified by the command argument for modification.
With SET and ZKILL, the target is a single node. In the case of KILL, the
target may represent an entire sub-tree of nodes. GT.M only matches the
trigger against the target node, and only invokes the trigger once for
each KILL command. GT.M does not check nodes in sub-trees to see whether
they have matching triggers.
|