File: ll-reportmanual.txt

package info (click to toggle)
lifelines 3.0.37.2-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 8,312 kB
  • ctags: 6,091
  • sloc: ansic: 52,969; xml: 7,212; sh: 4,382; makefile: 724; yacc: 591; perl: 170; sed: 16
file content (2333 lines) | stat: -rw-r--r-- 81,449 bytes parent folder | download
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