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
|
THE LIFELINES PROGRAMMING SUBSYSTEM AND REPORT GENERATOR
LifeLines Version 3.0.37
Thomas T. Wetmore , IV
_____________________________________________________________
Table of Contents
Report Programming Manual
INTRODUCTION
LIFELINES PROGRAMMING REFERENCE
Procedures and Functions
Comments
Statements
Expressions
Include Feature
Built-in Functions
Value Types
Arithmetic and Logic Functions
Person Functions
Family Functions
Other types of records
List Functions
Table Functions
GEDCOM Node Functions
Event and Date Functions
Value Extraction Functions
User Interaction Functions
String Functions
Output Mode Functions
Person Set Functions and GEDCOM Extraction
Record Update Functions
Record Linking Functions
Miscellaneous Functions
Deprecated Functions
_____________________________________________________________
Report Programming Manual
INTRODUCTION
The LifeLines programming subsystem lets you produce reports in
any style or layout. You may generate files in troff, Postscript,
TeX, SGML or any other ASCII-based format, for further text
processing and printing. You access the report generator by
choosing the r command from the main menu. You may also use the
programming subsystem to create query and other processing
programs that write their results directly upon the screen. For
example, there is a LifeLines program that computes the
relationship between any two persons in a database.
Each LifeLines program is written in the LifeLines programming
language, and the programs are stored in normal files. When you
direct LifeLines to run a program, it asks you for the name of the
program file, asks you where you want the program's output
written, and then runs the program.
For example, say you want LifeLines to generate an ahnentafel.
Such a report might look like:
Example 1. Example of ahnentafel report
1. Thomas Trask WETMORE IV
b. 18 December 1949, New London, Connecticut
2. Thomas Trask WETMORE III
b. 15 October 1925, New London, Connecticut
3. Joan Marie HANCOCK
b. 6 June 1928, New London, Connecticut
4. Thomas Trask WETMORE Jr
b. 5 May 1896, New London, Connecticut
d. 8 November 1970, New London, Connecticut
5. Vivian Genevieve BROWN
b. 5 April 1896, Mondovi, Wisconsin
6. Richard James HANCOCK
b. 18 August 1904, New London, Connecticut
d. 24 December 1976, Waterford, Connecticut
7. Muriel Armstrong SMITH
b. 28 October 1905, New Haven, Connecticut
8. Thomas Trask WETMORE Sr
b. 13 March 1866, St. Mary's Bay, Nova Scotia
d. 17 February 1947, New London, Connecticut
9. Margaret Ellen KANEEN
b. 27 October 1859, Liverpool, England
d. 10 May 1900, New London, Connecticut
... lots more
Here is a LifeLines program that generates this report:
Example 2. Example of ahnentafel report script
proc main ()
{
getindi(indi)
list(ilist)
list(alist)
enqueue(ilist, indi)
enqueue(alist, 1)
while (indi, dequeue(ilist)) {
set(ahnen, dequeue(alist))
d(ahnen) ". " name(indi) nl()
if (e, birth(indi)) { " b. " long(e) nl() }
if (e, death(indi)) { " d. " long(e) nl() }
if (par, father(indi)) {
enqueue(ilist, par)
enqueue(alist, mul(2,ahnen))
}
if (par,mother(indi)) {
enqueue(ilist, par)
enqueue(alist, add(1,mul(2,ahnen)))
}
}
}
Say this program is in the file ahnen. When you choose the r
option from the main menu, LifeLines asks:
What is the name of the report program?
enter string:
You enter ahnen. Since the program generates a report, LifeLines
asks where to write that report:
What is the name of the output file?
enter file name:
You enter a file name, say my.ahnen. LifeLines reads the program
ahnen, executes the program, and writes the report output to
my.ahnen. LifeLines reports any syntax or run-time errors found
while trying to run the program.
A LifeLines program is made up of procedures and functions; every
program must contain at least one procedure named main. The main
procedure runs first; it may call other procedures, functions and
built-in functions. In the ahnentafel example there is only one
procedure.
A procedure body is a sequence of statements. In the example
program the first five statements are:
getindi(indi)
list(ilist)
list(alist)
enqueue(ilist, indi)
enqueue(alist, 1)
The first statement calls the getindi (get individual) built-in
function, which causes LifeLines to ask you to identify a person
using the zip browse style of identification:
Identify person for interpreted report
enter name:
After you identify a person, he or she is assigned to the variable
indi. The next two statements declare two list variables, ilist
and alist. Lists hold sequences of things; there are operations
for placing things on lists, taking things off, and iterating
through the list elements. In the example, ilist holds a list of
ancestors, in ahnentafel order, who have not yet been reported on,
and alist holds their respective ahnentafel numbers.
The next two statements call the enqueue function, adding the
first members to both lists. The person identified by the getindi
function is made the first member of ilist, and the number one,
this person's ahnentafel number, is made the first member of
alist.
The rest of the program is:
while (indi, dequeue(ilist)) {
set(ahnen, dequeue(alist))
d(ahnen) ". " name(indi) nl()
if (e, birth(indi)) { " b. " long(e) nl() }
if (e, death(indi)) { " d. " long(e) nl() }
if (par, father(indi)) {
enqueue(ilist, par)
enqueue(alist, mul(2,ahnen))
}
if (par, mother(indi)) {
enqueue(ilist, par)
enqueue(alist, add(1,mul(2,ahnen)))
}
}
This is a loop that iteratively removes persons and their
ahnentafel numbers from the two lists, and then prints their names
and birth and death information. If the persons have parents in
the database, their parents and their parents' ahnentafel numbers
are then put at the ends of the lists. The loop iterates until the
list is empty.
The loop is a while loop statement. The line:
while (indi, dequeue(ilist)) {
removes (via dequeue) a person from ilist, and assigns the person
to variable indi. As long as there are persons on ilist, another
iteration of the loop follows.
The statement:
set(ahnen, dequeue(alist))
is an assignment statement. The second argument is evaluated; its
value is assigned to the first argument, which must be a variable.
Here the next number in alist is removed and assigned to variable
ahnen. This is the ahnentafel number of the person just removed
from ilist.
The line:
d(ahnen) ". " name(indi) nl()
contains four expression statements; when expressions are used as
statements, their values, if any, are treated as strings and
written directly to the report output file. The d function
converts its integer argument to a numeric string. The ". " is a
literal (constant) string value. The name function returns the
default form of a person's name. The nl function returns a string
containing the newline character.
The next two lines:
if (e, birth(indi)) { " b. " long(e) nl() }
if (e, death(indi)) { " d. " long(e) nl() }
write out basic birth and death information about a person. These
lines are if statements. The second argument in the conditional is
evaluated and assigned to the first argument, which must be a
variable. The first if statement calls the birth function,
returning the first birth event in a person's record. If the event
exists it is assigned to variable e, and the body (the items
between the curly brackets) of the if statement is executed. The
body consists of three expression statements: a literal, and calls
to the long and nl functions. Long takes an event and returns the
values of the first DATE and PLAC lines in the event.
Finally in the program is:
if (par, father(indi)) {
enqueue(ilist,par)
enqueue(alist,mul(2,ahnen))
}
if (par,mother(indi)) {
enqueue(ilist,par)
enqueue(alist,add(1,mul(2,ahnen)))
}
These lines add the father and mother of the current person, if
either or both are in the database, to ilist. They also compute
and add the parents' ahnentafel numbers to alist. A father's
ahnentafel number is twice that of his child. A mother's
ahnentafel number is twice that of her child plus one. These
values are computed with the mul and add functions.
_____________________________________________________________
LIFELINES PROGRAMMING REFERENCE
LifeLines programs are stored in files you edit with a screen
editor. Programs are not edited from within the LifeLines program;
edit them as you would any text file. The programs may be stored
in any directories; they do not have to be kept in or associated
with LifeLines databases. You may set the LLPROGRAMS shell
variable to hold a list of directories that LifeLines will use to
automatically search for programs when you request program
execution.
_____________________________________________________________
Procedures and Functions
A LifeLines program is made up of one or more procedures and
functions. A procedure has format:
proc name(params) { statements }
Name is the name of the procedure, params is an optional list of
parameters separated by commas, and statements is a list of
statements that make up the procedure body. Report generation
begins with the first statement in the procedure named main.
Procedures may call other procedures and functions. Procedures are
called with the call statement described below.When a procedure is
called, the statements making up its body are executed.
A function has format:
func name(params) { statements }
Name, params and statements are defined as in procedures.
Functions may call other procedures and functions. When a function
is called the statements that make it up are executed. A function
differs from a procedure by returning a value to the procedure or
function that calls it. Values are returned by the return
statement, described below. Recursive functions are allowed. A
function is called by invoking it in an expression.
Function and procedure parameters are passed by value except for
list, set and table types which are passed by reference.
Redeclaration of a parameter instantiates a new variable of the
stated or implied type. The previous instance continues to exist
in the scope of the caller.
_____________________________________________________________
Comments
You may comment your LifeLines programs using the following
notation:
/*...comment text including any characters except */... */
Comments begin with a /* and end with a */. Comments may appear on
lines of their own or on lines that have program constructs.
Comments may span many lines. Comments may not be nested.
_____________________________________________________________
Statements
There are a number of statement types. The simplest is an
expression statement, an expression that is not part of any other
statement or expression. Expressions are defined more fully below.
An expression statement is evaluated, and if its value is non-null
(non-zero), it is assumed to be a string, and written to the
program output file. If its value is null, nothing is written to
the output file. For example, the expression
name(indi)
, where indi is a person, returns the person's name and writes it
to the output file. On the other hand, the expression
set(n, nspouses(indi))
assigns the variable n the number of spouses that person indi has,
but since set returns null, nothing is written to the output file.
The programming language includes if statements, while statements
and procedure call statements, with the following formats:
if ([varb,] expr) { statements }
[ elsif ([varb], expr) { statements } ]*
[ else { statements } ]
while ([varb,] expr ) { statements }
call name(args)
Square brackets indicate optional parts of the statement syntax.
An if statement is executed by first evaluating the conditional
expression in the if clause. If non-zero, the statements in the if
clause are evaluated, and the rest of the if statement, if any, is
ignored. If the value is zero, and there is an elsif clause
following, the conditional in the elsif clause is evaluated, and
if non-zero, the statements in that clause are executed.
Conditionals are evaluated until one of them is non-zero, or until
there are no more. If no conditional is non-zero, and if the if
statement ends with an else clause, the statements in the else
clause are executed. There are two forms of conditional
expressions. If the conditional is a single expression, it is
simply evaluated. If the conditional is a variable followed by an
expression, the expression is evaluated and its value is assigned
to the variable.
Note that if treats null strings as false, but empty strings as
true. This has the benefit that
if (birth(indi))
will return true if there is a BIRT record, even if it is empty,
but will return false if there is no BIRT record at all.
The while statement provides a looping mechanism. The conditional
is evaluated, and if non-zero, the body of the loop is executed.
After each iteration the expression is reevaluated; as long as it
remains non-zero, the loop is repeated.
The call statement provides procedure calls. Name must match one
of the procedures defined in the report program. Args is a list of
argument expressions separated by commas. Recursion is allowed.
When a call is executed, the values of its arguments are evaluated
and used to initialize the procedure's parameters. The procedure
is then executed. When the procedure completes, execution resumes
with the first item after the call.
The following report language statements are commonly encountered
only near the top of a report:
char_encoding(string)
require(string)
option(string)
include(string)
global(varb)
The char_encoding statement specifies what character encoding
scheme is used by the report, so that the report processor can
correctly interpret bytes not in ASCII (e.g., accented letters).
An example specifying a character encoding common in Western
Europe:
char_encoding("ISO-8859-1")
The option statement allows the report writer to specify options.
The only option currently available is "explicitvars", which
causes any use of variables not previously declared or set to be
reported as a parsing error. The require statement allows the
report writer to specify that this report needs a version of the
report interpreter no older than that specified. The include
statement includes the contents of another file into the current
file; its string expression is the name of another LifeLines
program file. It is described in more detail below. The global
statement must be used outside the scope of any procedure or
function; it declares a variable to have global scope.
The report language also includes the following statements, which
mimic some common programming languages:
set(varb, expr)
continue()
break()
return([expr])
The set statement is the assignment statement; the expression is
evaluated, and its value is assigned to the variable. The continue
statement jumps to the bottom of the current loop, but does not
leave the loop. The break statement breaks out of the most closely
nested loop. The return statement returns from the current
procedure or function. Procedures have return statements without
expressions; functions have return statements with expressions.
None of these statements return a value, so none has a direct
effect on program output.
In addition to these conventional statements, the report generator
provides other iterator statements for looping through
genealogical and other types of data. For example, the children
statement iterates through the children of a family, the spouses
statement iterates through the spouses of a person, and the
families statement iterates through the families that a person is
a spouse or parent in. A number of arguments to the iterator are
set with values for each iteration. After completion of the
iteration, these variables have the value null. These iterators
and others are described in more detail later under the
appropriate data types.
_____________________________________________________________
Expressions
There are four types of expressions: literals, numbers, variables
and built-in or user defined function calls.
A literal is any string enclosed in double quotes; its value is
itself. A number is any integer or floating point constant; its
value is itself. A variable is a named location that can be
assigned different values during program execution. The value of a
variable is the last value assigned to it. Variables do not have
fixed type; at different times in a program, the same variable may
be assigned data of completely different types. An identifier
followed by comma-separated list of expressions enclosed in
parentheses, is either a call to a built-in function or a call to
a user-defined function.
_____________________________________________________________
Include Feature
The LifeLines programming language provides an include feature.
Using this feature one LifeLines program can refer to other
LifeLines programs. This feature is provided by the include
statement:
include(string)
where string is a quoted string that is the name of another
LifeLines program file. When an include statement is encountered,
the program that it refers to is read at that point, exactly as if
the contents of included file had been in the body of the original
file at that point. This allows you to create LifeLines program
library files that can be used by many programs. Included files
may in turn contain include statements, and so on to any depth.
LifeLines will use the LLPROGRAMS shell variable, if set, to
search for the include files. Each file included with a include
statement is only read once. If multiple include statements are
encountered that include the same file, only the first statement
has any effect.
The only main procedure actually executed is the one in the report
the user chose. main procedures in other reports which are
included do not get run. This allows a module intended to be
included in other programs to have a main procedure for test
purposes. If multiple functions or procedures with the same name
are included (other than the name main) a runtime error is
generated and the program is not run.
_____________________________________________________________
Built-in Functions
There is a long list of built-in functions, and this list will
continue to grow for some time. The first subsection below
describes the value types used in LifeLines programs; these are
the types of variables, function parameters and function return
values. In the remaining sections the built-in functions are
separated into logical categories and described.
_____________________________________________________________
Value Types
ANY
union of all types
BOOL
boolean (0 represents false; anything else represents true)
EVENT
event; reference to substructure of nodes in a GEDCOM
record (reference)
FAM
family; reference to a GEDCOM FAM record (reference)
FLOAT
floating point number (may be used anywhere an INT may be
used)
INDI
person; reference to a GEDCOM INDI record (reference)
INT
integer (on most systems a 32-bit signed value)
LIST
arbitrary length list of any values (reference)
NODE
GEDCOM node; reference to a line in a GEDCOM tree/record
(reference)
NUMBER
union of all arithmetic types (INT and FLOAT)
SET
arbitrary length set of persons (reference)
STRING
text string
TABLE
keyed look-up table (reference)
VOID
type with no values
In the summaries of built-in functions below, each function is
shown with its argument types and its return type. The types are
from the preceding list. Sometimes an argument to a built-in
function must be a variable; when this is so its type is given as
XXX_V, where XXX is one of the types above. The built-ins do not
check the types of their arguments. Variables can hold values of
any type, though at any one time they will hold values of only one
type. Note that EVENT is a subtype of NODE, and BOOL is a subtype
of INT. Built-ins with type VOID actually return null (zero)
values.
Reference types (denoted above in parentheses) obey "pointer
semantics", which is to say that assigning one to another variable
results in both variables pointing at the same data (no copy is
made). Therefore, if you pass a string to a function which changes
the string, the caller does not see the change, because a string
is not a reference type. On the other hand, if you pass a table to
a function which alters the table, the caller does see the change,
because a table is a reference type.
_____________________________________________________________
Arithmetic and Logic Functions
NUMBER add(NUMBER, NUMBER ...);
addition - two to 32 arguments
NUMBER sub(NUMBER, NUMBER);
subtraction
NUMBER mul(NUMBER, NUMBER ...);
multiplication - two to 32 arguments
NUMBER div(NUMBER, NUMBER);
division
INT mod(INT, INT);
modulus (remainder)
NUMBER exp(NUMBER, INT);
exponentiation
NUMBER neg(NUMBER);
negation
FLOAT float(INT);
convert int to float
INT int(FLOAT);
convert float to int
VOID incr(NUMBER);
increment variable by one
VOID decr(NUMBER);
decrement variable by one
BOOL and(BOOL, BOOL ...);
logical and - two to 32 arguments
BOOL or(BOOL, BOOL ...);
logical or - two to 32 arguments
BOOL not(BOOL);
logical not
BOOL eq(ANY, ANY);
equality (not strings)
BOOL ne(ANY, ANY);
non-equality
BOOL lt(ANY, ANY);
less than
BOOL gt(ANY, ANY );
greater than
BOOL le(ANY, ANY);
less than or equal
BOOL ge(ANY, ANY);
greater than or equal
Add, sub, mul and div do normal arithmetic of integer or floating
values. If any operand is float, the result is float. Functions
add and mul can have two to 32 arguments; the sum or product of
the full set of arguments is computed. Functions sub and div have
two arguments each; sub subtracts its second argument from its
first, and div divides its first argument by its second. The mod
function returns the remainder after dividing the first parameter
by the second. If the second argument to div or mod is zero, these
functions return 0 and generate a run time error. Exp performs
integer exponentiation. Neg negates its argument. The functions
float and int can be used to explicitly convert a value to float
or int where needed.
Incr and decr increment by one and decrement by one, respectively,
the value of a variable. The argument to both functions must be a
variable.
And and or do logical operations. Both functions take two to 32
arguments. All arguments are and'ed or or'ed together,
respectively. The arguments are evaluated from left to right, but
only up to the point where the final value of the function becomes
known. Not does the logical not operation.
Eq, ne, lt, le, gt and ge evaluate the six ordering relationships
between two integers.
_____________________________________________________________
Person Functions
STRING name(INDI, BOOL);
default name of
STRING fullname(INDI, BOOL, BOOL, INT);
many name forms of
STRING surname(INDI);
surname of
STRING givens(INDI);
given names of
STRING trimname(INDI, INT);
trimmed name of
EVENT birth(INDI);
first birth event of
EVENT death(INDI);
first death event of
EVENT baptism(INDI);
first baptism event of
EVENT burial(INDI);
first burial event of
INDI father(INDI);
first father of
INDI mother(INDI);
first mother of
INDI nextsib(INDI);
next (younger) sibling of
INDI prevsib(INDI);
previous (older) sibling of
STRING sex(INDI);
sex of
BOOL male(INDI);
male predicate
BOOL female(INDI);
female predicate
STRING pn(INDI, INT);
pronoun referring to
INT nspouses(INDI);
number of spouses of
INT nfamilies(INDI);
number of families (as spouse/parent) of
FAM parents(INDI);
first parents' family of
STRING title(INDI);
first title of
STRING key(INDI|FAM, BOOL);
internal key of (work for families also)
STRING soundex(INDI);
SOUNDEX code of
NODE inode(INDI);
root GEDCOM node of
NODE root(INDI);
root GEDCOM node of
INDI indi(STRING);
find person with key value
INDI firstindi(void);
first person in database in key order
INDI lastindi(void);
last person in database in key order
INDI nextindi(INDI);
next person in database in key order
INDI previndi(INDI);
previous person in database in key order
spouses (INDI, INDI, FAM, INT) { commands }
loop through all spouses of
families (INDI, FAM, INDI, INT) { commands }
loop through all families (as spouse) of
forindi (INDI, INT) { commands }
loop through all persons in database
mothers (INDI, INDI_V, FAM_V, INT) { commands }
loop through all female parents of a person
fathers (INDI, INDI_V, FAM_V, INT) { commands }
loop through all male parents of a person
Parents (INDI, FAM, INT) { commands }
loop through all familes a person is a child of
These functions take a person as a parameter and return
information about him or her.
Name returns the default name of a person; this is the name found
on the first 1 NAME line in the person's record; the slashes are
removed and the surname is made all capitals; name can take an
optional second parameter - if it is true the function acts as
described above; if false, the surname is kept exactly as it is in
the record.
Fullname returns the name of a person in a variety of formats. If
the second parameter is true the surname is shown in upper case;
otherwise the surname is as in the record. If the third parameter
is true the parts of the name are shown in the order as found in
the record; otherwise the surname is given first, followed by a
comma, followed by the other name parts. The fourth parameter
specifies the maximum length field that can be used to show the
name; various conversions occur if it is necessary to shorten the
name to fit this length.
Surname returns the surname of the person, as found in the first 1
NAME line; the slashes are removed. Givens returns the given names
of the person in the same order and format as found in the first 1
NAME line of the record. Trimname returns the default name of the
person trimmed to the maximum character length given in the second
variable.
Birth, death, baptism and burial return the first birth, death,
baptism and burial event in the person's record, respectively. An
event is a level 1 GEDCOM node. If there is no matching event
these functions return null.
Father, mother, nextsib and prevsib return the father, mother,
next younger sibling and next older sibling of the person,
respectively. If the person has more than one father (mother) the
father (mother) function returns the first one. These functions
return null if there is no person in the role.
Sex returns the person's sex as the string M if the person is
male, F if the person is female, or U if the sex of the person is
not known. Male and female return true if the person is male or
female, respectively, or false if not.
Pn generates pronouns, useful when generating English text; the
second parameter selects the type of pronoun:
0 He/She
1 he/she
2 His/Her
3 his/her
4 him/her
Nspouses returns the number of spouses the person has in the
database, and nfamilies returns the number of families the person
is a parent/spouse in; these two values are not necessarily the
same. Parents returns the first family that the person is a child
in.
Title returns the value of the first 1 TITL line in the record.
Key returns the key value of a person or family; it there is a
second parameter and it is non-null, the leading I or F will be
stripped. Soundex returns the Soundex code of the person.
Root and Inode return the root node of the person's GEDCOM node
tree. Note that an INDI value is not a NODE value. If you want to
process the nodes within a person node tree, you must first use
the root or inode function to get the root of the person node
tree. Root and inode are synonyms.
Indi returns the person who's key is passed as an argument; if no
person has the key indi returns null.
Firstindi, nextindi and previndi allow you to iterate through all
persons in the database. Firstindi returns the first person in the
database in key order. Nextindi returns the next person after the
argument person in key order. Previndi returns the previous person
before the argument person in key order.
Spouses is an iterator that loops through each spouse a person
has. The first argument is a person. The second argument is a
person variable that iterates through the first person's spouses.
The third argument is a family variable that iterates through the
families the person and each spouse are in. The fourth argument is
an integer variable that counts the iterations.
Families is an iterator that loops through the families a person
was a spouse/parent in. The first argument is a person. The second
argument is a family variable that iterates through the families
the first person was a spouse/parent in. The third argument
iterates through the spouses from the families; if there is no
spouse in a particular family, the variable is set to null for
that iteration. The fourth argument is an integer variable that
counts the iterations.
Forindi is an iterator that loops through every person in the
database in ascending key order. Its first parameter is a variable
that iterates through the persons; its second parameter is an
integer counter variable that counts the persons starting at one.
mothers is an iterator that loops through every female parent of
the specified individual. Its first parameter is a person; its
third parameter is a family variable that iterates through the
familes that the person is a child in; its second parameter is a
person variable that is the female parent associated with the
family in the third parameter; The fourth parameter is a variable
that counts the families returned starting at one.
Parents is an iterator that loops through every family that a
person is a child in. Note: This iterator's name begins with a
capital P. There is another function of the same name that begins
with a lower case p. Its first parameter is a person; its second
parameter is a family variable that iterates through the familes
that the person is a child in; and the third parameter is a
variable that counts the families returned starting at one.
Forindi is an iterator that loops through every person in the
database in ascending key order. Its first parameter is a variable
that iterates through the persons; its second parameter is an
integer counter variable that counts the persons starting at one.
_____________________________________________________________
Family Functions
EVENT marriage(FAM);
first marriage event of
INDI husband(FAM);
first husband/father of
INDI wife(FAM);
first wife/mother of
INT nchildren(FAM);
number of children in
INDI firstchild(FAM);
first child of
INDI lastchild(FAM);
last child of
STRING key(FAM|INDI, BOOL);
internal key of (works for persons also)
NODE fnode(FAM);
root GEDCOM node of
NODE root(FAM);
root GEDCOM node of
FAM fam(STRING);
find family from key
FAM firstfam(void);
first family in database in key order
FAM lastfam(void);
last family in database in key order
FAM nextfam(FAM);
next family in database in key order
FAM prevfam(FAM);
previous family in database in key order
children (FAM, INDI_V, INT_V) { commands }
loop through children of family
forfam (FAM_V, INT_V) { commands }
loop through all families in database
These functions take a family as an argument and return
information about it.
Marriage returns the first marriage event found in the family
record, if any; it returns null if there is no marriage event.
Husband returns the first husband/father of the family, if any;
and wife returns the first wife/mother of the family, if any. Each
returns null if the requested person is not in the family.
Nchildren returns the number of children in the family.
Firstchild and lastchild return the first child and last child in
a family, respectively.
Key was described in the section on person functions.
Root and fnode return the root node of a family GEDCOM node tree.
Note that a FAM value is not a NODE value. If you want to process
the nodes within a family node tree, you must first use root or
fnode function to get the root of the family node tree. Root and
fnode are synonyms.
Fam returns the family who's key is passed as an argument; if no
family has the key fam returns null.
Firstfam, nextfam and prevfam allow you to iterate through all
families in the database. Firstfam returns the first family in the
database in key order. Nextfam returns the next family after the
argument family in key order. Prevfam returns the previous family
before the argument family in key order.
Children is an iterator that loops through the children in a
family. Its first parameter is a family expression; its second
parameter is a variable that iterates through each child; its
third parameter is an integer counter variable that counts the
children starting at one. These two variables may be used within
the loop body.
Forfam is an iterator that loops through every family in the
database in ascending key order. Its first parameter is a variable
that iterates through the families; its second parameter is an
integer counter variable that counts the families starting at one.
_____________________________________________________________
Other types of records
forsour (NODE_V, INT) { commands }
loop through all sources in database
foreven (NODE_V, INT) { commands }
loop through all EVEN nodes in database
forothr (NODE_V, INT) { commands }
loop through all other (notes, etc.) nodes in database
forsour is an iterator that loops through all the Source nodes in
the database. Its first argument is the SOUR record and its second
parameter is an integer counter variable that counts the sources
elements starting at one. foreven is an iterator that loops
through all the Event nodes in the database. Its first argument is
the EVEN record and its second parameter is an integer counter
variable that counts the events elements starting at one. forothr
is an iterator that loops through all the Other nodes in the
database. Its first argument is the record (NOTE, etc.) and its
second parameter is an integer counter variable that counts the
nodes starting at one.
_____________________________________________________________
List Functions
VOID list(LIST_V);
declare a list
BOOL empty(LIST);
check if list is empty
INT length(LIST);
length of list
VOID enqueue(LIST, ANY);
enqueue element on list
ANY dequeue(LIST);
dequeue and return element from list
VOID requeue(LIST, ANY);
requeue an element on list
VOID push(LIST, ANY);
push element on list
ANY pop(LIST);
pop and return element from list
VOID setel(LIST, INT, ANY);
array element assignment
ANY getel(LIST, INT);
array element selection
BOOL inlist(LIST, ANY);
is second argument in list.
VOID sort(LIST, LIST);
sort list elements
VOID rsort(LIST, LIST);
reverse sort list elements
LIST dup(LIST);
duplicate a list
forlist (LIST, ANY_V, INT_V) { commands }
loop through all elements of list
LifeLines provides general purpose lists that can be accessed as
queues, stacks or arrays. A list must be declared with the list
function before it can be used. Redeclaring an existing variable
with the list clears it and restores it to being an empty list. If
the argument to list() is the name of a parameter to the current
routine, the reference to the calling routines list is removed and
a new list is created.
A list can have any number of elements. Empty returns true if the
list has no elements and false otherwise. Length returns the
length of the list. The only parameter to both is a list. The
following diagram indicates how the various access functions for a
list interact:
[listops.jpg]
Enqueue, dequeue and requeue provide queue access to a list.
Enqueue adds an element to the back of a queue, dequeue removes
and returns the element from the front of a queue, and requeue
adds an element to the front of a queue. The first parameter to
all three is a list, and the second parameter to enqueue and
requeue is the value to be added to the queue and can be any
value.
Push and pop provide stack access to a list. Push pushes an
element on the stack, and pop removes and returns the most
recently pushed element from the stack. The first parameter to
both is a list, and the second parameter to push is the value to
be pushed on the stack and can be of any type.
Setel and getel provide array access to a list. Setel sets a value
of an array element, and getel returns the value of an array
element. The first parameter to both is a list; the second
parameter to both is an integer index into the array; and the
third parameter to setel is the value to assign to the array
element and can be of any type. Array elements are indexed
starting at one. Unassigned elements are assumed to be null (0).
Arrays automatically grow in size to accommodate the largest index
value that is used. Passing 0 references the last element at the
other end from 1, and -1 the one before it, etc.
inlist compares the second argument with each element in the list.
If it finds a match inlist returns true.
sort and rsort sort a list, using the elements of the second array
to determine the new order. Both lists are reordered, so
essentially both are sorted using the sort order of the second
argument. (If only one argument is given, it is sorted on its own
elements.) rsort sorts in order reverse of sort. The order that
sort produces places the smallest element at position 1, and the
largest element at the end of the list, such that dequeue will
remove the smallest element.
dup creates a copy of a list. If b is a list, the function
set(a,b) makes the variable a a reference to the list b. If you
want to make a new list, you must use set(a,dup(b)).
Forlist is an iterator that loops through the element in a list.
Its first parameter is a LIST expression; its second parameter is
a variable that iterates through the list elements; and its third
parameter is an integer counter variable that counts the list
elements starting at one.
_____________________________________________________________
Table Functions
VOID table(TABLE_V);
declare a table
VOID insert(TABLE, STRING, ANY);
insert entry in table
ANY lookup(TABLE, STRING);
lookup and return entry from table
These functions provide general purpose, keyed tables. A table
must be declared with the table function before it can be used.
Insert adds an object and its key to a table. Its first parameter
is a table; the second parameter is the object's key; and the
third parameter is the object itself. The key must be a string and
the object can be any value. If there already is an object in the
table with that key, the old object is replaced with the new.
Lookup retrieves an object from a table. Its first parameter is a
table, and the second parameter is the object's key. The function
returns the object with that key from the table; if there is no
such object, null is returned.
_____________________________________________________________
GEDCOM Node Functions
STRING xref(NODE);
cross reference index of
STRING tag(NODE);
tag of
STRING value(NODE);
value of
NODE parent(NODE);
parent node of
NODE child(NODE);
first child of
NODE sibling(NODE);
next sibling of
NODE savenode(NODE);
copy a node structure
INT level(NODE);
level of a node
fornodes (NODE, NODE_V) { commands }
loop through child nodes
fornotes (ANY, STRING) { commands }
loop through notes on a node
traverse (NODE, NODE_V, INT_V) { commands }
loop through all descendent nodes
These functions provide access to the components of a GEDCOM node.
All take a GEDCOM node as their only parameter, and each returns a
different value associated with the node.
Xref returns the cross reference index of the node, if any; tag
returns the tag of the node; and value returns the value of the
node, if any. If there is no cross reference, xref returns null;
if there is no value, value returns null.
Parent returns the parent node of the node, if any; child returns
the first child node of the node, if any; and sibling returns the
next sibling node of the node, if any. Whenever there is no such
related node, these functions return null. These three functions
allow simple navigation through a GEDCOM node tree.
Savenode makes a copy of the node, and the substructure of nodes
below the node, that is passed to it. Beware: the memory used to
make the copy is never returned to the system.
The level function returns the level of the node.
Fornodes is an iterator that loops through the child nodes of a
GEDCOM node. Its first argument is a node expression, and its
second parameter is a variable that iterates through each direct
child node of the first node.
Fornotes is an iterator that loops through the NOTE nodes of a
GEDCOM node. Its first argument is a node expression, and its
second parameter is a variable that returns the value of the NOTE.
The value includes processed sub CONC and CONT records.
Traverse is an iterator providing a general method for traversing
GEDCOM trees. Its first parameter is a node expression; its second
parameter is a variable that iterates over every node under the
first node in a top down, left to right manner; and its third
parameter is a variable that is set to the level of the current
node in the iteration.
_____________________________________________________________
Event and Date Functions
STRING date(EVENT);
date of, value of first DATE line
STRING place(EVENT);
place of, value of first PLAC line
STRING year(EVENT);
year or, 1st string of 3-4 digits in 1st DATE line
STRING long(EVENT);
date and place, values of 1st DATE and PLAC lines
STRING short(EVENT);
date and place of, abbreviated from
EVENT gettoday(void);
returns the `event' of the current date
VOID dayformat(INT);
set day format for stddate calls
VOID monthformat(INT);
set month format for stddate calls
VOID yearformat(INT);
set year format for stddate calls
VOID eraformat(INT);
set era format for stddate calls
VOID dateformat(INT);
set date format for stddate calls
VOID datepic(STRING);
set custom date format for stddate calls
STRING stddate(EVENT|STRING);
date of, in current format
VOID complexformat(INT);
set complex date format
VOID complexpic(INT, STRING);
set custom complex date picture string
STRING complexdate(EVENT|STRING);
date of, in current complex format
These functions extract information about the dates and places of
events.
Date returns the value of the first DATE line in an event, a node
in a GEDCOM record tree. Date finds the first DATE line one level
deeper than the event node. Place returns the value of the first
PLAC line in an event. Year returns the first three or four digit
number in the value of the first DATE line in an event; this
number is assumed to be the year of the event.
Long returns the verbatim values of the first DATE and PLAC lines
in an event, concatenated together and separated by a comma. Short
abbreviates information from the first DATE and PLAC lines,
concatenates the shortened information together with a comma
separator and returns it. An abbreviated date is its year; an
abbreviated place is the last component in the value, further
abbreviated if the component has an entry in the place
abbreviation table.
Gettoday creates an event that has today's date in the DATE line.
The next seven functions are used to format dates in a variety of
ways. Dayformat, monthformat, yearformat, eraformat, and
dateformat select style options for formatting the day, month,
year, era, and overall date structure; stddate returns dates in
the selected style. datepic allows specifying a custom pattern
that overrides the date format selected with dateformat. The
string supplied specifies the placement of the day, month and year
in the string with %d, %m and %y. A null argument disables the
overrided format. The argument to stddate is normally an event and
the date is extracted from the event and formatted. If the
argument is a date string it is converted using the current date
formats.
The next three functions provide for more complex formatting of
dates. Taking into account the abt, est, cal, bef, aft, fr and to
qualifiers on GEDCOM dates. complexformat selects the format to
use. The format effects only the complex picture, not the format
of the date itself. The function complexpic can be used to specify
a custom picture string for any or all of the 9 custom format
strings. The custom string can be canceled by passing a null for
the string. When a custom picture string is provided it overrides
both the abbreviated and full word picture strings. complexdate
formats the date similarly to stddate, but with the addition of
the complex date format string selected.
The day format codes passed to dayformat are:
0 leave space before single digit days
1 use leading 0 before single digit days
2 no space or leading 0 before single digit days
The month format codes passed to monthformat are:
0 number with space before single digit months
1 number with leading zero before single digit months
2 number with no space or zero before single digit months
3 upper case abbreviation (eg, JAN, FEB) (localized)
4 capitalized abbreviation (eg, Jan, Feb) (localized)
5 upper case full word (eg, JANUARY, FEBRUARY) (localized)
6 capitalized full word (eg, January, February) (localized)
7 lower case abbreviation (eg, jan, feb) (localized)
8 lower case full word (eg, january, february) (localized)
9 upper case abbreviation in English per GEDCOM (eg, JAN, FEB)
10 lower case roman letter (eg, i, ii)
11 upper case roman letter (eg, I, II)
The year format codes passed to yearformat are:
0 use leading spaces before years with less than four digits
1 use leading 0 before years with less than four digits
2 no space or leading 0 before years
The era format codes passed to eraformat are:
0 no AD/BC markers
1 trailing B.C. if appropriate
2 trailing A.D. or B.C.
11 trailing BC if appropriate
12 trailing AD or BC
21 trailing B.C.E. if appropriate
22 trailing C.E. or B.C.E.
31 trailing BC if appropriate
32 trailing CE or BCE
The full date formats passed to stddate are:
0 da mo yr
1 mo da, yr
2 mo/da/yr
3 da/mo/yr
4 mo-da-yr
5 da-mo-yr
6 modayr
7 damoyr
8 yr mo da
9 yr/mo/da
10 yr-mo-da
11 yrmoda
12 yr (year only, omitting all else)
13 da/mo yr
14 (As in GEDCOM)
The complex date formats selected by the complexformat and used by
complexdate are:
Mode Example
3 use abbreviations in uppercase ABT 1 JAN 2002
4 use abbreviations in titlecase Abt 1 JAN 2002
5 use uppercased full words ABOUT 1 JAN 2002
6 use titlecased full words About 1 JAN 2002
7 use abbreviations in lowercase abt 1 JAN 2002
8 use lowercase full words about 1 JAN 2002
The complex date string pictures that can be overridden with the
complexpic are:
Abbreviation Full word
0 abt %1 about %1
1 est %1 estimated %1
2 cal %1 calculated %1
3 bef %1 before %1
4 aft %1 after %1
5 bet %1 and %2 between %1 and %2
6 fr %1 from %1
7 to %1 to %1
8 fr %1 to %2 from %1 to $2
_____________________________________________________________
Value Extraction Functions
VOID extractdate(NODE, INT_V, INT_V, INT_V);
extract a date
VOID extractnames(NODE, LIST_V, INT_V, INT_V);
extract a name
VOID extractplaces(NODE, LIST_V, INT_V);
extract a place
VOID extracttokens(STRING, LIST_V, INT_V, STRING);
extract tokens
VOID extractdatestr(VARB, VARB, VARB, VARB, VARB, STRING);
extract date from string
Value extraction functions read the values of certain lines and
return those values in extracted form.
Extractdate extracts date values from either an event node or DATE
node. The first parameter must be a node; if its tag is DATE, the
date is extracted from the value of that node; if its tag is not
DATE, the date is extracted from the first DATE line one level
below the argument node. The remaining three arguments are
variables. The first is assigned the integer value of the
extracted day; the second is assigned the integer value of the
extracted month; and the third is assigned the integer value of
the extracted year.
Extractnames extracts name components from a NAME line. Its first
argument is either an INDI or a NAME node. If it is a NAME line,
the components are extracted from the value of that node; if it is
an INDI line, the components are extracted from the value of the
first NAME line in the person record. The second argument is a
list that will hold the extracted components. The third argument
is an integer variable that is set to the number of extracted
components. The fourth argument is a variable that is set to the
index (starting at one) of the surname component; the / characters
are removed from around the surname component. If there is no
surname this argument variable is set to zero.
Extractplaces extracts place components from a PLAC node. The
first argument is a node; if its tag is PLAC, the places are
extracted from the value of the node; if its tag is not PLAC,
places are extracted from the first PLAC line one level below the
argument node. The second parameter is a list that will hold the
extracted components. The third argument is an integer variable
that is set to the number of extracted components. Place
components are defined by the comma-separated portions of the PLAC
value; leading and trailing white space is removed from the
components, while all internal white space is retained.
Extracttokens extracts tokens from a string and places them in a
list. The first argument is the string to extract tokens from. The
second argument is the list to hold the tokens. The third argument
is an integer variable that is set to the number of tokens
extracted. The fourth parameter is the string of delimiter
characters that extracttokens uses to break the input string into
tokens.
extractdatestr extracts date values from a . STRING. It is
intended for internal verification of date extraction code. The
remaining five arguments are variables. The second is assigned the
integer value of the extracted day; the third is assigned the
integer value of the extracted month; and the fourth is assigned
the integer value of the extracted year.
_____________________________________________________________
User Interaction Functions
VOID getindi(INDI_V, STRING);
identify person through user interface
VOID getindiset(SET_V, STRING);
identify set of persons through user interface
VOID getfam(FAM_V);
identify family through user interface
VOID getint(INT_V, STRING);
get integer through user interface
VOID getstr(STRING_V, STRING);
get string through user interface
INDI choosechild(INDI|FAM);
select child of person/family through user interface
FAM choosefam(INDI);
select family person is in as spouse
INDI chooseindi(SET);
select person from set of persons
INDI choosespouse(INDI);
select spouse of person
SET choosesubset(SET);
select a subset of persons from set of persons
INT menuchoose(LIST, STRING);
select from a list of options
These functions interact with the user to get information needed
by the program.
Getindi asks the user to identify a person. The first argument is
a variable that is set to the person. The second is an optional
string to use as a prompt. Getindiset asks the user to identify a
set of persons. Getfam asks the user identify a family. Getint and
getstr ask the user enter an integer and string, respectively.
Choosechild asks the user select a child of a family or person;
its single argument is a person or family; it return the child.
Choosefam has the user select a family that a person is in as a
spouse; its argument is a person; it returns the family.
Chooseindi has the user select one person from a set of persons;
its argument in a set of persons; it returns the chosen person.
Choosespouse has the user select a spouse of a person; its
argument is a person; it returns the chosen spouse. Choosesubset
has the user select a subset of persons from a set of persons; its
argument is the chosen subset.
Menuchoose allows the user to select from an arbitrary menu. The
first argument is a list of strings making up the items in the
menu; the second, optional argument is a prompt string for the
menu; menuchoose returns the integer index of the item selected by
the user; if the user doesn't select an item, zero is returned.
_____________________________________________________________
String Functions
STRING lower(STRING);
convert to lower case
STRING upper(STRING);
convert to upper case
STRING capitalize(STRING);
capitalize first letter
STRING titlecase(STRING);
capitalize first letter of each word
STRING trim(STRING, INT);
trim to length
STRING rjustify(STRING, INT);
right justify in field
STRING concat(STRING, STRING ...);
catenate two strings
STRING strconcat(STRING, STRING ...);
catenate two strings
INT strlen(STRING);
number of characters in string
STRING substring((STRING, INT, INT);
substring function
INT index(STRING, STRING, INT);
index function
STRING d(INT);
number as decimal string
STRING f(FLOAT, INT);
number as floating point string
STRING card(INT);
number in cardinal form (one, two, ...)
STRING ord(INT);
number in ordinal form (first, second, ...)
STRING alpha(INT);
convert number to Latin letter (a, b, ...)
STRING roman(INT);
number in Roman numeral form (i, ii, ...)
STRING strsoundex(STRING);
find SOUNDEX value of arbitrary string
INT strtoint(STRING);
convert numeric string to integer
INT atoi(STRING);
convert numeric string to integer
INT strcmp(STRING, STRING);
general string compare
BOOL eqstr(STRING, STRING);
compare strings for equality
BOOL nestr(STRING, STRING);
compare strings for inequality
These functions provide string handling. Prior to version 3.0.6,
many of them used an approach to memory management chosen for
absolute minimal memory footprint. A function using this approach
constructed its output string in its own string buffer, reusing
that buffer each time it was called. When a function using this
approach returned a string value it returned its buffer. In
consequence the strings returned by these functions were to be
either used or saved before the function was called again.
Lower and upper convert the letters in their arguments to lower or
upper case, respectively. Capitalize converts the first character
of the argument, if it is a letter, to upper case. Lower and upper
historically used the buffer return method; capitalize operates on
and returns its argument. titlecase converts the first letter of
each word if it is a letter, to upper case and all other
characters to lower case.
Trim shortens a string to the length specified by the second
parameter. If the string is already of that length or shorter the
string is not changed. Rjustify right justifies a string into
another string of the length specified by the second parameter. If
the original string is shorter than the justified string, blanks
are inserted to the left of the original string; if the string is
longer than the justified string, the original string is truncated
on the right. Trim historically used the buffer return method;
rjustify creates and returns a new string.
Concat and strconcat catenate strings and return the result. They
are identical functions. They may take two to 32 string arguments;
null arguments are allowed. The arguments are concatenated
together into a single, newly allocated string, which is returned.
Strlen returns the length of the string argument.
Substring returns a substring of the first argument string. The
second and third arguments are the indices of the first and last
characters in the argument string to use to form the substring.
The indexes are relative one. Substring historically used the
buffer return method.
Index returns the character index of the nth occurrence of a
substring within a string. The index is the relative one character
offset to the beginning of the substring. The first argument is
the string; the second argument is the substring; and the third
argument is the occurrence number.
D, card, ord, alpha and roman convert integers to strings. D
converts an integer to a numeric string; card converts an integer
to a cardinal number string (eg, one, two, three); ord converts an
integer to an ordinal number (eg, first, second, third); alpha
converts an integer to a letter (eg, a, b, c); and roman converts
an integer to a Roman numeral (eg, i, ii, iii).
The f function converts a float to a string. The optional second
argument specifies the precision of the output. The default
precision is 2.
Strsoundex converts an arbitrary string to a SOUNDEX value.
Non-ASCII text characters are ignored in the string.
Strtoint converts a numeric string to an integer. Atoi is
identical to strtoint.
Strcmp compares two strings and returns an integer that is less
than zero, equal to zero, or greater than zero, if, respectively,
the first string is lexicographically less than, equal to, or
greater than the second string. Eqstr and nestr return whether two
strings are equal or not equal, respectively. Strcmp, Eqstr, and
nestr all treat null strings as empty strings, which is to say
they pretend that a null string is actually "". This means that
all null and empty strings compare as equal.
_____________________________________________________________
Output Mode Functions
VOID linemode(void);
use line output mode
VOID pagemode(INT, INT);
use page output mode with given page size
VOID col(INT);
position to column in output
INT getcol(void);
get current column in output
VOID row(INT);
position to row in output
VOID pos(INT, INT);
position to (row, col) coordinate in output
VOID pageout(void);
output page buffer
STRING nl(void);
newline character
STRING sp(void);
space character
STRING qt(void);
double quote character
VOID newfile(STRING, BOOL);
send program output to this file
STRING outfile(void);
return name of current program output file
VOID copyfile(STRING);
copy file contents to program output file
VOID print(STRING, STRING ...);
print string to standard output window
Reports can be generated in two modes, line mode and page mode.
Linemode selects line mode and pagemode selects page mode; line
mode is the default. The first parameter to pagemode is the number
of rows per page; the second parameter is the number of columns
per page. When in the line mode report output is written directly
to the output file as the program runs, line by line. When in page
mode output is buffered into pages which are written to the output
file when pageout is called. Page mode is useful for generating
charts (eg, pedigree charts or box charts) where it is convenient
to compute the two-dimensional location of output.
Col positions output to the given column. If the current column is
greater than the argument, col positions output to the given
column on the next line. Col works in both modes. Getcol returns
the current column in the output.
Row positions output to the first character in the given row; row
can only be used in page mode.
Pos positions output to a specified row and column coordinate; the
first argument specifies the row, and the second specifies the
column. Pos can only be used in page mode.
Nl write a new line character to the output file; sp writes a
space character to the output file; and qt writes a quote
character to the output file. Note that \n and \' can be used
within string values to represent the newline and double quote
characters.
Newfile specifies the name of the report output file. Its first
argument is the file's name; its second argument is an append flag
- if its value is non-zero the report appends to this file; if its
value is zero the report overwrites the contents of the file.
Newfile can be called many times; this allows a single report
program to generate many report output files during one execution.
Programs are not required to use newfile; if it is not used then
LifeLines automatically asks for the name of the report output
file.
Outfile returns the name of the current report output file.
Copyfile copies the contents of a file to the report output file;
its argument is a string whose value is the name of a file; if the
file name is not absolute nor relative, then the LLPROGRAMS
environment variable, if set, will be used to search for the file;
the file is opened and its contents copied to the report output
file.
Print prints its argument string to the standard output window;
print may have one to 32 arguments.
_____________________________________________________________
Person Set Functions and GEDCOM Extraction
VOID indiset(SET_V);
declare a set variable
SET addtoset(SET, INDI, ANY);
add a person to a set
SET deletefromset(SET, INDI, BOOL);
remove a person from a set
INT lengthset(SET);
size of a set
SET union(SET, SET);
union of two sets
SET intersect(SET, SET);
intersection of two sets
SET difference(SET, SET);
difference of two sets
SET parentset(SET);
set of all parents
SET childset(SET);
set of all children
SET spouseset(SET);
set of all spouses
SET siblingset(SET);
set of all siblings
SET ancestorset(SET);
set of all ancestors
SET descendentset(SET);
set of all descendents
SET descendantset(SET);
same as descendentset; spelling
SET uniqueset(SET);
remove duplicates from set
VOID namesort(SET);
sort indiset by name
VOID keysort(SET);
sort indiset by key values
VOID valuesort(SET);
sort indiset by auxiliary values
VOID genindiset(STRING, SET);
generate indiset from GEDCOM name string
BOOL inset(SET, INDI);
true if the Individual is in the set.
forindiset( SET, INDI_V, ANY_V, INT_V ) { commands }
loop through all persons in person set
These functions allow you to manipulate person sets. A person set
is a potentially large set of persons; each person may have an
arbitrary value associated with him/her. A person set must be
declared with the indiset function before it can be used.
Addtoset adds a person to a set. The first argument is the set;
the second argument is the person; and the third argument may be
any value. The same person may be added to a set more than once,
each time with a different value. Deletefromset removes a person
from a set. The first argument is the set; the second argument is
the person; if the third parameter is true all of the person's
entries are removed from the set; if false only the first entry is
removed. Lengthset returns the number of persons in a person set.
Union, intersect and difference return the set union, set
intersection and set difference, respectively, of two person sets.
Each functions takes two person sets as arguments and returns a
third person set. The functions actually modify their argument
sets, both reordering them into canonical key order and removing
any duplicates (these operations are necessary to easily implement
these types of set functions).
Parentset, childset, spouseset and siblingset return the set of
all parents, set of all children, set of all spouses and set of
all siblings, respectively, of the set of persons in their
argument. In all cases there is no change to the argument person
set.
Ancestorset returns the set all ancestors of all persons in the
argument set. Descendentset returns the set of all descendents of
all persons in the argument set. Descendantset is the same as
descendentset; it allows an alternate spelling.
Uniqueset sorts a person set by key value and then removes all
entries with duplicate keys; the input set is modified and
returned.
Namesort, keysort and valuesort sort a set of persons by name, by
key and by associated value, respectively.
Each person in a person set has an associated value. When a person
is added to a set with addtoset, the value is explicitly assigned.
When new sets are created by other functions, a number of rules
are used to associate values with persons as they are added to the
new sets. For parentset, childset and spouseset the values are
copied from the first input set person that causes the new person
to be added to the set. For union, intersect and difference, the
values are copied from the values in the first input set, except
in the case of union, when persons are taken from the second set
alone, in which case the values come from there. For ancestorset
and descendantset the value is set to the number of generations
the new person is away from the first person in the input set that
the new person is related to. If the new person is related to more
than one person in the input set, the value is set for the nearest
relationship; that is, the value is as low as possible. Valuesort
sorts a person set by the values of these auxiliary values.
Genindiset generates the set of persons that matches a string
whose value is a name in GEDCOM format. Genindiset uses the same
algorithm that matches names entered at the browse prompt or by
the user interaction getindiset function.
Inset returns true if the the specified individual is in the SET.
Forindiset is an iterator that loops through each person in an
indiset. The first parameter is an indiset. The second parameter
is a variable that iterates through each person in the set. The
third parameter iterates through the values associated with the
persons. The fourth parameter is an integer variable that counts
the iterations.
_____________________________________________________________
Record Update Functions
NODE createnode(STRING, STRING);
create a GEDCOM node
VOID addnode(NODE, NODE, NODE);
add a node to a GEDCOM tree
VOID detachnode(NODE);
delete a node from a GEDCOM tree
VOID writeindi(INDI);
write a person back to the database
VOID writefam(FAM);
write a family back to the database
These functions allow you to modify an internal GEDCOM node tree.
Createnode creates a GEDCOM node; the two arguments are tag and
value strings, respectively; the value string can be null. Addnode
adds a node to a node tree. The first argument is the new node;
the second is the node in the tree that becomes the parent of the
new node; the third is the node in the tree that becomes the
previous sibling of the new node; this argument is null if the new
node is to become the first child of the parent. Detachnode
removes a node from a node tree. writeindi writes an individual
record back to the database, and writefam writes a family record
back to the database, allowing the report to make permanent
changes to the database.
The node functions only change data in memory; there is no effect
on the database until and unless writeindi or writefam are called.
These functions may be changed or extended in the future to allow
database changes.
_____________________________________________________________
Record Linking Functions
BOOL reference(STRING);
determine if string is a cross reference
NODE dereference(STRING);
reference cross reference or key to node tree
NODE getrecord(STRING);
same as dereference
These functions allow you to recognize values that are cross
references and to read the records they refer to. Reference
returns true if its string argument is a cross reference value,
that is, the internal key of one of the records in the database.
Dereference returns the node tree of the record referred to by its
cross reference string argument. Getrecord is a synonym for
dereference.
_____________________________________________________________
Miscellaneous Functions
VOID lock(INDI|FAM);
lock a person or family in memory
VOID unlock(INDI|FAM);
unlock a person or family from memory
STRING database(void);
return name of current database
STRING program(void);
return name of current program
STRING version(void);
return version of LifeLines program
VOID system(STRING);
execute string as a UNIX shell command
INT heapused(void);
amount of heap used for windows
STRING getproperty(STRING);
extract system or user property. Function available after
v3.0.5.
STRING setlocale(STRING);
set the locale
STRING bytecode(STRING, STRING);
encode a string in a codeset
STRING convertcode(STRING, STRING, STRING);
convert string from one codeset to another
VOID debug(BOOLEAN);
set interperter debug mode
STRING pvalue(ANY);
dump information about a pvalue
VOID free(ANY);
free space associated with a variable
Lock and unlock are used to lock a person or family into RAM
memory, and to unlock a person or family from RAM memory,
respectively.
Database returns the name of the current database, useful in
titling reports. program returns the name of the current report
program. Version returns the version of the running LifeLines
program, eg, 3.0.37.
System executes its string argument as a UNIX (or MS-Windows as
appropriate) shell command, by invoking the system shell. This
will not occur if the user has chosen to disallow report system
calls (via the DenySystemCalls user option).
The heapused function returns the amount of system heap that is in
use at the time. This is implemented only on windows.
The getproperty function extracts system or user properties.
Properties are named group.subgroup.property, group.property or
even property. The keys are available at the moment can be found
in the ll-userguide under System and User Properties.
The setlocale function sets the locale and returns the previous
setting of locale.
The bytecode function converts the supplied string with escape
codes to the current codeset, or to the codeset specified by the
optional second parameter if specified. A escaped code is a dollar
sign ($) followed by 2 hex characters, e.g. $C1.
The convertcode function converts a string to another codeset. In
the two argument form, the second argument is the destination
codeset, and the source codeset is the internal codeset. In the 3
argument form, the second argument is the source codeset and the
third argument is the destination codeset.
The debug function turns on or off programming debugging. When
enabled gobs of information is printed as a LifeLines program is
run. This can be useful to figure out why a program is not
behaving as expected.
The pvalue function returns a string that represents the contents
of a variable in the interpreter. This is present for debug
purposes.
The function free deallocates space associated with the variable
provided as argument 1. Care must be taken when free is used in a
function on a variable which is a parameter to the function. free
will not effect the variable in the calling program.
_____________________________________________________________
Deprecated Functions
The functionality of the following three functions, getindimsg,
getintmsg and getstrmsg is now available using the optional
parameter of getindi, getint and getstr. These functions should no
longer be used as they will be removed from a future version of
Lifelines.
VOID getindimsg(INDI_V, STRING);
identify person through user interface
VOID getintmsg(INT_V, STRING);
get integer through user interface
VOID getstrmsg(STRING_V, STRING);
get string through user interface
Three functions are available for to generate GEDCOM format output
to the report output file of all persons in the argument person
set. These functions do not in most cases generate consistent and
usable output. This can be done with a program, but it is
suggested that these routines are probably not what you really
wanted.
Gengedcom output contains a person record for each person in the
set, and all the family records that link at least two of the
persons in the set together. This function is provided for
backward compatibility. Source, Event and Other(X) record pointers
are output unmodified, but none of their records are output - this
yields an inconsistent output.
Gengedcomweak output does not contain Source, Event or Other(X)
record pointers or their records. Gengedcomstrong includes the
Source, Event and Other(X) record pointers and all top-level nodes
referenced by them.
VOID gengedcom(SET);
generate GEDCOM file from person set
VOID gengedcomweak(SET);
generate GEDCOM file from person set
VOID gengedcomstrong(SET);
generate GEDCOM file from person set
By the release of version 3.0.6, all string values are local
copies, and the save and strsave functions should be entirely
unnecessary. Save is present only for compatibility reasons.
Previously it duplicated its argument (to prevent strings from
becoming stale; this is not currently necessary (and this function
no longer does anything). Strsave is the same function as save.
STRING save(STRING);
save and return copy of string
STRING strsave(STRING);
same as save function
Use detachnode instead of deletenode.
VOID deletenode(NODE);
delete a node from a GEDCOM tree
|