diff --git a/.gitattributes b/.gitattributes index 74299ea3efcd7a0e9302009af4004a2b511cafb0..8fb40028b833743fc07f8c8b2455b80675183f0b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,6 @@ [attr]binary -text -crlf -diff -ident * text ident +*.gif binary *.gz binary testfont binary diff --git a/tutorial/array.fig b/tutorial/array.fig new file mode 100644 index 0000000000000000000000000000000000000000..cfc67f21fe2dd40dcb482f5574a3c3c6908aab32 --- /dev/null +++ b/tutorial/array.fig @@ -0,0 +1,24 @@ +#FIG 3.1 +Landscape +Center +Inches +1200 2 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 10 + 600 600 600 4200 900 3900 1200 4200 1500 3900 1800 4200 + 2400 3900 2700 4200 2700 600 600 600 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 600 1200 2700 1200 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 600 1800 2700 1800 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 600 2400 2700 2400 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 600 3000 2700 3000 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 600 3600 2700 3600 +4 0 -1 0 0 0 12 0.0000 4 135 765 900 900 Element 0\001 +4 0 -1 0 0 0 12 0.0000 4 135 765 900 1500 Element 1\001 +4 0 -1 0 0 0 12 0.0000 4 135 765 900 2100 Element 2\001 +4 0 -1 0 0 0 12 0.0000 4 135 765 900 2700 Element 3\001 +4 0 -1 0 0 0 12 0.0000 4 180 435 600 600 Array\001 +4 0 -1 0 0 0 12 0.0000 4 135 765 900 3300 Element 4\001 diff --git a/tutorial/array.gif b/tutorial/array.gif new file mode 100644 index 0000000000000000000000000000000000000000..d21670f8f8b78dc9e41d08604791b2443df431bd Binary files /dev/null and b/tutorial/array.gif differ diff --git a/tutorial/function.fig b/tutorial/function.fig new file mode 100644 index 0000000000000000000000000000000000000000..010712f1c61c68a788d2712f510182b2ef737134 --- /dev/null +++ b/tutorial/function.fig @@ -0,0 +1,61 @@ +#FIG 3.1 +Landscape +Center +Inches +1200 2 +6 600 1200 3000 4800 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 1500 2700 1500 2700 2100 900 2100 900 1500 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 2700 2700 2700 2700 3900 900 3900 900 2700 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 600 1200 3000 1200 3000 4800 600 4800 600 1200 +4 0 -1 0 0 0 12 0.0000 4 180 1200 1200 1800 Program pointer\001 +4 0 -1 0 0 0 12 0.0000 4 135 570 1200 3300 records\001 +-6 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2700 1800 4500 1800 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 4800 2400 6900 2400 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 4800 3000 6900 3000 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 4800 3600 6900 3600 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 4800 4200 6900 4200 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 4800 2100 3600 2100 3600 3300 2700 3300 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 1 + 4800 4800 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 4800 1800 6900 1800 6900 4800 4800 4800 4800 1800 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 11 + 4500 1200 4500 6300 8700 6300 8400 5700 9000 5400 8400 4500 + 8700 3900 8400 3000 8700 1800 8400 1200 4500 1200 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 6000 2700 6000 2700 6600 900 6600 900 6000 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 6900 2700 6900 2700 7500 900 7500 900 6900 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 600 5700 3000 5700 3000 7800 600 7800 600 5700 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2400 6000 2400 4800 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 2700 7200 3900 7200 3900 4500 4800 4500 +4 0 -1 0 0 0 12 0.0000 4 180 510 900 1200 Object\001 +4 0 -1 0 0 0 12 0.0000 4 180 630 4500 1200 Program\001 +4 0 -1 0 0 0 12 0.0000 4 135 780 4800 1800 Identifiers\001 +4 0 -1 0 0 0 12 0.0000 4 135 750 5100 2100 1. records\001 +4 0 -1 0 0 0 12 0.0000 4 180 555 5100 2325 4 bytes\001 +4 0 -1 0 0 0 12 0.0000 4 135 540 5100 2700 2. main\001 +4 0 -1 0 0 0 12 0.0000 4 180 915 5100 3300 3. find_song\001 +4 0 -1 0 0 0 12 0.0000 4 180 1080 5100 3900 4. list_records\001 +4 0 -1 0 0 0 12 0.0000 4 180 1215 5100 4500 5. delete_record\001 +4 0 -1 0 0 0 12 0.0000 4 180 1140 900 2700 Variable space\001 +4 0 -1 0 0 0 12 0.0000 4 135 660 900 5700 Function\001 +4 0 -1 0 0 0 12 0.0000 4 135 1245 1200 7200 Identifer number\001 +4 0 -1 0 0 0 12 0.0000 4 180 1080 1200 6300 Object pointer\001 diff --git a/tutorial/function.gif b/tutorial/function.gif new file mode 100644 index 0000000000000000000000000000000000000000..7acf06ec2d92873e0171a54a303b5b6053ce4e5a Binary files /dev/null and b/tutorial/function.gif differ diff --git a/tutorial/inherit.fig b/tutorial/inherit.fig new file mode 100644 index 0000000000000000000000000000000000000000..2eb5665a05be086eba4dc1595294c7e8a5b427af --- /dev/null +++ b/tutorial/inherit.fig @@ -0,0 +1,131 @@ +#FIG 3.1 +Landscape +Center +Inches +1200 2 +6 900 3900 8400 8100 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 1200 6600 1200 6600 1200 6600 1200 6600 1200 6600 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 1200 6300 1200 6300 1200 6300 1200 6300 1200 6300 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6975 6825 6975 6825 6975 6825 6975 6825 6975 6825 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6900 6975 6900 6975 6900 6975 6900 6975 6900 6975 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 5400 3000 5400 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 6000 3000 6000 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 3900 8400 3900 8400 8100 900 8100 900 3900 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 5700 4800 7800 4800 7800 5400 5700 5400 5700 4800 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 1200 4800 3000 4800 3000 7200 1200 7200 1200 4800 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 6600 3000 6600 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 5700 6000 7800 6000 7800 7800 5700 7800 5700 6000 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 5700 6900 7800 6900 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 3000 6300 5700 6300 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 3000 6900 5100 6900 5100 7200 5700 7200 +4 0 -1 0 0 0 12 0.0000 4 135 780 1200 4800 Identifiers\001 +4 0 -1 0 0 0 12 0.0000 4 135 585 6000 4800 Inherits\001 +4 0 -1 0 0 0 12 0.0000 4 180 765 1200 4200 Program 2\001 +4 0 -1 0 0 0 12 0.0000 4 180 765 6000 5100 Program 1\001 +4 0 -1 0 0 0 12 0.0000 4 135 630 1500 5100 Records\001 +4 0 -1 0 0 0 12 0.0000 4 180 1245 1500 5400 4 bytes (copied)\001 +4 0 -1 0 0 0 12 0.0000 4 180 900 1500 5700 list_records\001 +4 0 -1 0 0 0 12 0.0000 4 180 735 1500 6300 find_song\001 +4 0 -1 0 0 0 12 0.0000 4 180 1035 1500 6900 delete_record\001 +4 0 -1 0 0 0 12 0.0000 4 135 390 6000 6000 Code\001 +4 0 -1 0 0 0 12 0.0000 4 180 735 6000 6600 find_song\001 +4 0 -1 0 0 0 12 0.0000 4 180 1035 6000 7500 delete_record\001 +-6 +6 900 8700 8400 13500 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 1200 11400 1200 11400 1200 11400 1200 11400 1200 11400 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 1200 11100 1200 11100 1200 11100 1200 11100 1200 11100 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6975 11625 6975 11625 6975 11625 6975 11625 6975 11625 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6900 11775 6900 11775 6900 11775 6900 11775 6900 11775 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 10200 3000 10200 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 10800 3000 10800 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 11400 3000 11400 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 5700 9600 7800 9600 7800 10800 5700 10800 5700 9600 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 5700 10200 7800 10200 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 12000 3000 12000 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 1200 9600 3000 9600 3000 12600 1200 12600 1200 9600 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 5700 11700 7800 11700 7800 13200 5700 13200 5700 11700 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 3000 12300 5700 12300 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 8700 8400 8700 8400 13500 900 13500 900 8700 +4 0 -1 0 0 0 12 0.0000 4 135 780 1200 9600 Identifiers\001 +4 0 -1 0 0 0 12 0.0000 4 135 585 6000 9600 Inherits\001 +4 0 -1 0 0 0 12 0.0000 4 135 630 1500 9900 Records\001 +4 0 -1 0 0 0 12 0.0000 4 180 1245 1500 10200 4 bytes (copied)\001 +4 0 -1 0 0 0 12 0.0000 4 180 900 1500 10500 list_records\001 +4 0 -1 0 0 0 12 0.0000 4 180 735 1500 11100 find_song\001 +4 0 -1 0 0 0 12 0.0000 4 180 1035 1500 11700 delete_record\001 +4 0 -1 0 0 0 12 0.0000 4 180 765 1200 9000 Program 3\001 +4 0 -1 0 0 0 12 0.0000 4 180 765 6000 9900 Program 2\001 +4 0 -1 0 0 0 12 0.0000 4 180 1455 6000 10500 Program 1 (copied)\001 +4 0 -1 0 0 0 12 0.0000 4 135 360 1500 12300 main\001 +4 0 -1 0 0 0 12 0.0000 4 135 390 6000 11700 Code\001 +4 0 -1 0 0 0 12 0.0000 4 135 360 6000 12300 main\001 +-6 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6975 3525 6975 3525 6975 3525 6975 3525 6975 3525 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6900 3675 6900 3675 6900 3675 6900 3675 6900 3675 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 1200 1500 3000 1500 3000 2700 1200 2700 1200 1500 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 2100 3000 2100 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 5700 1500 7800 1500 7800 3000 5700 3000 5700 1500 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 3000 2400 3900 2400 3900 1800 5700 1800 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 3 + 3000 5700 3900 5700 3900 2400 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 7800 9900 9000 9900 9000 7500 8400 7500 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 3 + 7800 10500 9600 10500 9600 5100 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 7800 5100 9600 5100 9600 2700 8400 2700 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 3 + 3000 11700 5100 11700 5100 7200 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 3 + 3000 11100 4500 11100 4500 6300 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 3 + 3000 10500 3900 10500 3900 5700 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 600 8400 600 8400 3300 900 3300 900 600 +4 0 -1 0 0 0 12 0.0000 4 135 780 1200 1500 Identifiers\001 +4 0 -1 0 0 0 12 0.0000 4 135 390 6000 1500 Code\001 +4 0 -1 0 0 0 12 0.0000 4 135 630 1500 1800 Records\001 +4 0 -1 0 0 0 12 0.0000 4 180 555 1500 2100 4 bytes\001 +4 0 -1 0 0 0 12 0.0000 4 180 900 1500 2400 list_records\001 +4 0 -1 0 0 0 12 0.0000 4 180 900 6000 2100 list_records\001 +4 0 -1 0 0 0 12 0.0000 4 180 765 1200 900 Program 1\001 diff --git a/tutorial/inherit.gif b/tutorial/inherit.gif new file mode 100644 index 0000000000000000000000000000000000000000..c0d8bf7d440f9716e3c3dc7fe4eba7903eb3ec2e Binary files /dev/null and b/tutorial/inherit.gif differ diff --git a/tutorial/mapping.fig b/tutorial/mapping.fig new file mode 100644 index 0000000000000000000000000000000000000000..a8b89dd130af844396c70c62f828225ec50370b2 --- /dev/null +++ b/tutorial/mapping.fig @@ -0,0 +1,81 @@ +#FIG 3.1 +Landscape +Center +Inches +1200 2 +6 900 900 3600 1500 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 900 2100 900 2100 1500 900 1500 900 900 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2100 1200 2400 1200 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 2400 900 3600 900 3600 1500 2400 1500 2400 900 +4 0 -1 0 0 0 12 0.0000 4 135 420 1200 1200 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 450 2700 1200 Value\001 +-6 +6 1800 1800 4500 2400 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 1800 1800 3000 1800 3000 2400 1800 2400 1800 1800 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 3000 2100 3300 2100 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 3300 1800 4500 1800 4500 2400 3300 2400 3300 1800 +4 0 -1 0 0 0 12 0.0000 4 135 420 2100 2100 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 450 3600 2100 Value\001 +-6 +6 900 2700 3600 3300 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 2700 2100 2700 2100 3300 900 3300 900 2700 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2100 3000 2400 3000 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 2400 2700 3600 2700 3600 3300 2400 3300 2400 2700 +4 0 -1 0 0 0 12 0.0000 4 135 420 1200 3000 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 450 2700 3000 Value\001 +-6 +6 5100 1200 7800 1800 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 5100 1200 6300 1200 6300 1800 5100 1800 5100 1200 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 6300 1500 6600 1500 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6600 1200 7800 1200 7800 1800 6600 1800 6600 1200 +4 0 -1 0 0 0 12 0.0000 4 135 420 5400 1500 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 450 6900 1500 Value\001 +-6 +6 4500 3000 7200 3600 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 4500 3000 5700 3000 5700 3600 4500 3600 4500 3000 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 5700 3300 6000 3300 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6000 3000 7200 3000 7200 3600 6000 3600 6000 3000 +4 0 -1 0 0 0 12 0.0000 4 135 420 4800 3300 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 450 6300 3300 Value\001 +-6 +6 2400 3900 5100 4500 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 2400 3900 3600 3900 3600 4500 2400 4500 2400 3900 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 3600 4200 3900 4200 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 3900 3900 5100 3900 5100 4500 3900 4500 3900 3900 +4 0 -1 0 0 0 12 0.0000 4 135 420 2700 4200 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 450 4200 4200 Value\001 +-6 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 600 600 8100 600 8100 4800 600 4800 600 600 +3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 6 + 1 1 1.00 60.00 120.00 + 780 5175 1845 5175 2175 5070 2175 4695 990 4410 1665 3930 + 0.00 0.00 1393.80 5203.71 1660.05 5203.71 1925.19 5162.55 + 2106.76 5163.32 2248.89 4968.94 2255.26 4796.86 1914.13 4363.95 + 1042.73 4682.61 963.12 4271.05 1131.88 4151.05 0.00 0.00 +4 0 -1 0 0 0 12 0.0000 4 180 660 600 600 Mapping\001 +4 0 -1 0 0 0 12 0.0000 4 180 1260 345 5085 Lookup Function\001 diff --git a/tutorial/mapping.gif b/tutorial/mapping.gif new file mode 100644 index 0000000000000000000000000000000000000000..3d246fef085cc635fdf9f332177a70dcf2ed2fa1 Binary files /dev/null and b/tutorial/mapping.gif differ diff --git a/tutorial/multiset.fig b/tutorial/multiset.fig new file mode 100644 index 0000000000000000000000000000000000000000..c2afdb9afe46b963718ff4985fb44c1487453e27 --- /dev/null +++ b/tutorial/multiset.fig @@ -0,0 +1,33 @@ +#FIG 3.1 +Landscape +Center +Inches +1200 2 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 600 600 8100 600 8100 4800 600 4800 600 600 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 900 2100 900 2100 1500 900 1500 900 900 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 2700 2100 2700 2100 3300 900 3300 900 2700 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 1800 1800 3000 1800 3000 2400 1800 2400 1800 1800 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 5100 1200 6300 1200 6300 1800 5100 1800 5100 1200 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 4500 3000 5700 3000 5700 3600 4500 3600 4500 3000 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 2400 3900 3600 3900 3600 4500 2400 4500 2400 3900 +3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 6 + 1 1 1.00 60.00 120.00 + 780 5175 1845 5175 2175 5070 2175 4695 990 4410 1665 3930 + 0.00 0.00 1393.80 5203.71 1660.05 5203.71 1925.19 5162.55 + 2106.76 5163.32 2248.89 4968.94 2255.26 4796.86 1914.13 4363.95 + 1042.73 4682.61 963.12 4271.05 1131.88 4151.05 0.00 0.00 +4 0 -1 0 0 0 12 0.0000 4 180 1260 345 5085 Lookup Function\001 +4 0 -1 0 0 0 12 0.0000 4 135 420 1200 1200 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 420 1200 3000 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 420 2100 2100 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 420 5400 1500 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 420 4800 3300 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 420 2700 4200 Index\001 +4 0 -1 0 0 0 12 0.0000 4 135 645 600 600 Multiset\001 diff --git a/tutorial/multiset.gif b/tutorial/multiset.gif new file mode 100644 index 0000000000000000000000000000000000000000..fe6b0477c7d4ddcde86d03b1d3686ce1b9e372cd Binary files /dev/null and b/tutorial/multiset.gif differ diff --git a/tutorial/object.fig b/tutorial/object.fig new file mode 100644 index 0000000000000000000000000000000000000000..0c15e14b262953cbbba401fdab150273821b124f --- /dev/null +++ b/tutorial/object.fig @@ -0,0 +1,64 @@ +#FIG 3.1 +Landscape +Center +Inches +1200 2 +6 600 1200 3000 4800 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 1500 2700 1500 2700 2100 900 2100 900 1500 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 2700 2700 2700 2700 3900 900 3900 900 2700 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 600 1200 3000 1200 3000 4800 600 4800 600 1200 +4 0 -1 0 0 0 12 0.0000 4 180 1200 1200 1800 Program pointer\001 +4 0 -1 0 0 0 12 0.0000 4 135 570 1200 3300 records\001 +-6 +6 600 5400 3000 9000 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 5700 2700 5700 2700 6300 900 6300 900 5700 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 6900 2700 6900 2700 8100 900 8100 900 6900 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 600 5400 3000 5400 3000 9000 600 9000 600 5400 +4 0 -1 0 0 0 12 0.0000 4 180 1200 1200 6000 Program pointer\001 +4 0 -1 0 0 0 12 0.0000 4 135 570 1200 7500 records\001 +-6 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2700 1800 4500 1800 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 4800 2400 6900 2400 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 4800 3000 6900 3000 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 4800 3600 6900 3600 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 4800 4200 6900 4200 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 4800 2100 3600 2100 3600 3300 2700 3300 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 1 + 4800 4800 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 4800 1800 6900 1800 6900 4800 4800 4800 4800 1800 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 11 + 4500 1200 4500 6300 8700 6300 8400 5700 9000 5400 8400 4500 + 8700 3900 8400 3000 8700 1800 8400 1200 4500 1200 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2700 6000 4500 6000 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 3 + 1 1 1.00 60.00 120.00 + 3600 3300 3600 7500 2700 7500 +4 0 -1 0 0 0 12 0.0000 4 180 510 900 1200 Object\001 +4 0 -1 0 0 0 12 0.0000 4 180 630 4500 1200 Program\001 +4 0 -1 0 0 0 12 0.0000 4 135 780 4800 1800 Identifiers\001 +4 0 -1 0 0 0 12 0.0000 4 135 750 5100 2100 1. records\001 +4 0 -1 0 0 0 12 0.0000 4 180 555 5100 2325 4 bytes\001 +4 0 -1 0 0 0 12 0.0000 4 135 540 5100 2700 2. main\001 +4 0 -1 0 0 0 12 0.0000 4 180 915 5100 3300 3. find_song\001 +4 0 -1 0 0 0 12 0.0000 4 180 1080 5100 3900 4. list_records\001 +4 0 -1 0 0 0 12 0.0000 4 180 1215 5100 4500 5. delete_record\001 +4 0 -1 0 0 0 12 0.0000 4 180 1140 900 2700 Variable space\001 +4 0 -1 0 0 0 12 0.0000 4 180 510 900 5400 Object\001 +4 0 -1 0 0 0 12 0.0000 4 180 1140 900 6900 Variable space\001 diff --git a/tutorial/object.gif b/tutorial/object.gif new file mode 100644 index 0000000000000000000000000000000000000000..0b461d5938b9a068832eb43e2cd9e3d3267278b7 Binary files /dev/null and b/tutorial/object.gif differ diff --git a/tutorial/pike.gif b/tutorial/pike.gif new file mode 100644 index 0000000000000000000000000000000000000000..f3d7e20267b6fc008a9173362c634cf655cf431e Binary files /dev/null and b/tutorial/pike.gif differ diff --git a/tutorial/program.fig b/tutorial/program.fig new file mode 100644 index 0000000000000000000000000000000000000000..5350150e0d176f8df379b3a5f2abbf9f2971eeec --- /dev/null +++ b/tutorial/program.fig @@ -0,0 +1,64 @@ +#FIG 3.1 +Landscape +Center +Inches +1200 2 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 2100 3000 2100 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 2700 3000 2700 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 3300 3000 3300 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 1200 3900 3000 3900 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 4200 1500 6000 1500 6000 9000 4200 9000 4200 1500 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 3000 2400 3600 2400 3600 1800 4200 1800 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 3000 3000 3900 3000 3900 3900 4200 3900 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 4200 5100 6000 5100 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 4200 3300 6000 3300 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 + 4200 7200 6000 7200 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 3000 3600 3600 3600 3600 5400 4200 5400 +2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 3000 4200 3300 4200 3300 7500 4200 7500 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 1200 1500 3000 1500 3000 4500 1200 4500 1200 1500 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6900 1500 9000 1500 9000 2700 6900 2700 6900 1500 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6900 3600 9000 3600 9000 5100 6900 5100 6900 3600 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6900 3600 6900 3600 6900 3600 6900 3600 6900 3600 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 6900 3600 6900 3600 6900 3600 6900 3600 6900 3600 +2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 + 900 600 9900 600 9900 9300 900 9300 900 600 +4 0 -1 0 0 0 12 0.0000 4 180 630 1200 900 Program\001 +4 0 -1 0 0 0 12 0.0000 4 135 780 1200 1500 Identifiers\001 +4 0 -1 0 0 0 12 0.0000 4 135 750 1500 1800 1. records\001 +4 0 -1 0 0 0 12 0.0000 4 135 540 1500 2400 2. main\001 +4 0 -1 0 0 0 12 0.0000 4 180 915 1500 3000 3. find_song\001 +4 0 -1 0 0 0 12 0.0000 4 135 390 4200 1500 Code\001 +4 0 -1 0 0 0 12 0.0000 4 180 1080 1500 3600 4. list_records\001 +4 0 -1 0 0 0 12 0.0000 4 180 1215 1500 4200 5. delete_record\001 +4 0 -1 0 0 0 12 0.0000 4 135 360 4500 1800 main\001 +4 0 -1 0 0 0 12 0.0000 4 180 735 4500 3600 find_song\001 +4 0 -1 0 0 0 12 0.0000 4 180 900 4500 5400 list_records\001 +4 0 -1 0 0 0 12 0.0000 4 180 1125 4500 7500 delete_records\001 +4 0 -1 0 0 0 12 0.0000 4 180 1395 6900 1500 Debug information\001 +4 0 -1 0 0 0 12 0.0000 4 135 1020 7200 1800 Line numbers\001 +4 0 -1 0 0 0 12 0.0000 4 135 825 7200 2250 File names\001 +4 0 -1 0 0 0 12 0.0000 4 135 585 6900 3600 Inherits\001 +4 0 -1 0 0 0 12 0.0000 4 135 1050 7200 3900 Pointers to all\001 +4 0 -1 0 0 0 12 0.0000 4 180 1410 7200 4125 inherited programs\001 +4 0 -1 0 0 0 12 0.0000 4 180 555 1500 2025 4 bytes\001 diff --git a/tutorial/program.gif b/tutorial/program.gif new file mode 100644 index 0000000000000000000000000000000000000000..e111ef462f7b7ae9688e072ee5fafa2c04df1a9e Binary files /dev/null and b/tutorial/program.gif differ diff --git a/tutorial/tutorial.html b/tutorial/tutorial.html new file mode 100644 index 0000000000000000000000000000000000000000..be1cc7381ed2aa107013f4c553fde16b76fde215 --- /dev/null +++ b/tutorial/tutorial.html @@ -0,0 +1,9010 @@ +<html> +<title>Pike tutorial</title> +<body bgcolor="#A0E0C0" text="#000000" link=blue vlink=purple> +<p> +<center> +<h1> +Programming, using and understanding +<p> +<img src=pike.gif alt=PIKE> +<p> +<font size=+7><gh1>Pike</gh1></font> +<p> +</h1> +<h2>by Fredrik Hübinette</h2> +</center> + +<HR NEWPAGE> + +<h2> Preface </h2> + +This book was written with with the intention to make anybody with a little +programming experience able to use Pike. It should hopefully be possible to +gain a deep understanding of how Pike works and to some extent why it works +like it does from this book. It also teaches you how to write your own +extentions to Pike. I have been trying for years to get someone else to +write this book, but since it seems impossible without paying a fortune for +it I will have to do it myself. I hope that you will bear with me through +this book, and maybe we can both learn something. The book assumes that +you have programmed some other programming language before and that you +have some experience with UNIX. +<p> + +<HR NEWPAGE> + +<h1> Introduction </h1> + +This chapter will give you some background about Pike and this book +and also compare Pike with other languages. If you want to start +learning Pike immediately you can skip this chapter. + +<h2>Overview</h2> +The overall layout of this book had been made for people who want to +learn Pike fast. Since Pike is a simple language to learn, especially +if you have other programming experience, this should benefit most people. +Chapter one is devoted to background information about Pike and this book. +It is not really nesesary to read this chapter to learn how to use and +program pike, but it might help explain why some things work like they do. +It might be more interesting to re-read this chapter after you have +learned the basics of Pike programming. +Chapter two is where the action starts. It is a crash course in Pike with +examples and explanations about some of the basics. +<!-- FIXME (finish this overview) --> +<p> + +<h2> The history of Pike </h2> + +In the beginning, there was Zork. Then a bunch of people decided to make +multiplayer adventure games. One of those people was Lars Pensjö at the +Chalmers university in Gothemburg, Sweden. For his game he needed simple, +memory-efficient language, and thus LPC (Lars Pensjö C) was born. About a +year later I started playing one of these games and found that the language +was the most easy-to-use language I had ever encountered. I liked the language +so much that I started improving it and before long I had made my own LPC +dialect called LPC4. LPC4 was still geared towards writing adventure games, +but was quite useful for writing other things with as well. A major problem +with LPC4 was the copyright. Since it was based on Lars Pensjö's code, it +came with a license that did not allow it to be used for commercial gain. +So, in 1994 I started writing uLPC, which was a new but similar LPC interpreter. +I got financial backing from Signum Support AB for writing uLPC. Signum +is a company dedicated to supporting GNU and GPL software and they wanted +to create more GPL software. +<p> +When uLPC became usable, Informationsvävarna AB started using it for +their webserver. Before then, Roxen (then called Spinner) was non-commercial +and written in LPC4. Then in 1996 I started working for Informationsvävarna +developing uLPC for them. We also changed the name of uLPC to Pike to +get a more commercially viable name. +<p> + +<H2> A comparison with other languages </H2> +<dl> + +<dt> Python +<dd> Python is probably the language that is most like Pike. Pike is faster + and has better object orientation. It also has a syntax similar to + C++, which makes it more familiar for people who know C++. Python on + the other hand, has a lot more libraries available. + +<dt> C++ +<dd> Pike's syntax is almost the same as for C++. A huge differance is that + Pike is interpreted. This makes the code slower, but reduces compile times + to almost nothing. For those few applications which require the speed of + C or C++, it is often easier to write a Pike extention than to write the + whole thing in C or C++. + +<dt> Lisp and Scheme +<dd> Internally Pike has a lot in common with Lisp and Scheme. They are both + stack based, byte-compiled, interpreted languages. Pike is also + a 'one-cell' language, just like Scheme. + +<dt> Pascal +<dd> Pike has nothing in common with Pascal. + +<dt> Tcl/Tk +<dd> Pike is similar to Tcl/Tk in intent and they both have good string + handling. Pike has better data types and is much faster however. + On the other hand Tcl/Tk has X windows system support. +<!--The idea from the begining was similar but the implementation is very different.--> +</dl> + +<H2> What is Pike </H2> + +Pike is: +<ul> +<li> A programming language +<li> Object oriented +<li> Interpreted +<li> Fast +<li> Dynamic +<li> High-level +<li> similar to C++ +<li> easy to extend +<li> (a fish) +</ul> + +Pike has: +<ul> +<li> Garbage collection +<li> Advanced string functions +<li> 5 years of development behind it +<li> Advanced data types such as associative arrays +<li> Support for bignums +<li> Builtin socket support +</ul> +<p> +<h2>How to read this manual</h2> +This manual uses a couple of different typefaces to describe different +things: +<dl> +<dt><i>italics</i> +<dd>Italics is used as a placeholder for other things. If it says <i>a word</i> + in the text it means that you should put your own word there. +<dt><b>bold</b> +<dd>Bold is just used to emphasize that this word is not merely what it sounds + like. It is actually a <b>term</b>. +<dt><tt>fixedsize</tt> +<dd>Fixedsize is used to for examples and text directly from the computer. +</dl> +Also, please beware that the word <b>program</b> is also a builtin pike +data type. +<HR NEWPAGE> +<H1> Getting started</H1> +<p> +First you need to have pike installed on your computer. See Appendix E +"how to install Pike" if this is not already done. It is also vital +for the following examples that the pike binary is in your UNIX search +path. If you have problems with this, consult the manual for your shell +or go buy a beginners book about UNIX. +<p> +<h2> Your first Pike program </h2> +<pre> + int main() + { + write("hello world\n"); + return 0; + } +</pre> +Let's call this file hello_world.pike, and then we try to run it: +<p> +<pre> + $ pike hello_world.pike + hello world + $ +</pre> +<h2> Pretty simple, Let's see what everything means: + +</h2><pre> + int main() +</pre> +This begins the function <tt>main</tt>. Before the function name the type of value +it returns is declared, in this case <tt>int</tt> which is the name of the +integer number type in Pike. The empty space between the +parethesis indicates that this function takes no arguments. +A Pike program has to contain at least one function, the <tt>main</tt> function. This function is where program execution starts and thus the function from which every other function is called, directly or indirectly. We can say that this function is called by the operating system. +Pike is, as many other programming languages, built upon the concept of functions, i.e. what the program does is separated into small portions, or functions, each performing one (perhaps very complex) task. A function declaration consists of certain essential components; the type of the value it will return, the <i>name</i> of the function, the <i>parameters</i>, if any, it takes and the body of the function. A function is also a part of something greater; an object. You can program in Pike without caring about objects, but the programs you write will in fact be objects themselves anyway. +Now let's examine the body of <tt>main</tt>; +<p> +<pre> + { + write("hello world\n"); + return 0; + } +</pre> +Within the function body, programming instructions, statements, are grouped together in blocks. A block is as series of statements placed between curly brackets. Every statement has to end in a semicolon. This group of statements will +be executed every time the function is called. +<p> +<pre> + write("hello world\n"); +</pre> +The first statement is a call to the builtin function <tt>write</tt>. This will +execute the code in the function <tt>write</tt> with the arguments as input data. +In this case, the constant string <tt>hello world\n</tt> is sent. +Well, not quite. The <tt>\n</tt> combination corresponds to the newline +character. +<tt>write</tt> then writes this string to stdout when executed. Stdout is the standard Unix output channel, usually the screen. +<p> +<pre> + return 0; +</pre> +This statement exits the function and returns the value zero. Any statements +following the return statements will not be executed. +<p> +<h2>Improving hello_world.pike</h2> +Typing <tt>pike hello_world.pike</tt> to run our program may seem a bit +unpractical, fortunately, Unix provides us with a way of automating this +somewhat. If we modify hello_world.pike to look like this: +<p> +<pre> + #!/usr/local/bin/pike + + int main() + { + write("hello world\n"); + } +</pre> +And then we tell UNIX that hello_world.pike is executable so we can run +hello_world.pike without having to bother with running pike: +<p> +<pre> + $ chmod +x hello_world.pike + $ ./hello_wold.pike + hello world + $ +</pre> +N.B.: The hash bang (#!) must be first in the file, not even whitespace is allowed to precede it! +The file name after the hash bang must also be the complete file name to the Pike binary, and it may not exceed 30 characters. +<p> +<h2>Further improvements</h2> +Now, wouldn't it be nice if it said <tt>Hello world!</tt> instead of <tt>hello world</tt> ? +But of course we don't want to make our program "incompatible" with the old +version. Someone might need the program to work like it used to. +Therefore we'll add a <i>command line option</i> that will make it type the old +<tt>hello world</tt>. We also have to give the program the ability to choose +what it should output based on the command line optino. +This is what it could look like: +<p> +<pre> + #!/usr/local/bin/pike + + int main(int argc, string *argv) + { + if(argc > 1 && argv[1]=="--traditional") + { + write("hello world\n"); // old stype + }else{ + write("Hello world!\n"); // new style + } + return 0; + } +</pre> +Let's run it: +<p> +<pre> + $ chmod +x hello_world.pike + $ ./hello_world.pike + Hello world! + $ ./hello_world.pike --traditional + hello world + $ +</pre> +What is new in this version, then? +<pre> + int main(int argc, string *argv) +</pre> +In this version the space between the parentesis has been filled. +What it means is that <tt>main</tt> now takes two arguments. +One is called <tt>argc</tt>, and is of the type <tt>int</tt>. +The other is called <tt>argv</tt> and is a an array of strings. +A perhaps better way to represent an array of strings would be +<tt>array(string)</tt> which is exactly the same as <tt>string *</tt> +and probably easier to understand. The syntax <tt>string *</tt> +is more like the syntax in C/C++ however. +<p> +The arguments to <tt>main</tt> are taken from the command line when the +Pike program is executed. The first argument, <tt>argc</tt>, is how many +words were written on the command line (including the command itself) and +<tt>argv</tt> is an array formed by these words. +<p> +<pre> + if(argc > 1 && argv[1] == "--traditional") + { + write("hello world\n"); // old stype + }else{ + write("Hello world!\n"); // new style + } +</pre> +This is an if-else statement, it will execute what's between the first set +of brackets if the expression between the parenthesis evaluate to something +other than zero. Otherwise what's between the second set of brackets will +be executed. Let's look at that expression: +<p> +<pre> + argc > 1 && argv[1] == "--traditional" +</pre> +Loosely translated, this means: argc is greater than one, and the second +element in the array argv is equal to the string <tt>--traditional</tt>. Since +argc is the number of words on the command line the first part is true only +if there was anything after the program invocaton. +<p> +Also note the comments: +<p> +<pre> + write("hello world\n"); // old stype +</pre> +The <tt>//</tt> begins a comment which continues to the end of the line. +Comments lets you type in text in the program which will be ignored by the +computer. This is to inform whoever might read your code (like yourself) of +what the program does to make it easier to understand. +Comments are also allowed to look like C-style comments, ie. <tt>/* ... */</tt>, which can extend over several lines. The <tt>//</tt> comment only extends to the end of the line. +<p> + +<H2> Control structures </H2> +The first thing to understand about Pike is that just like any other +programming language it executes one piece of code at a time. Most of +the time it simply executes code line by line working its way downwards. +Just excuting a long list of instructions is not enough to make an interesting +program however. Therefore we have <b>control structures</b> to make Pike +execute pieces of code in more interesting orders than from top to bottom. +<p> +We have already seen an example of the <tt>if</tt> statement: +<pre> + if( <i>expression </i> ) + <i>statement1 </i> ; + else + <i>statement2 </i> ; +</pre> +If simply evaluates the expression and if the result is true it executes +statement1, otherwise it executes statement2. If you have no need for +statement2 you can leave out the whole else part like this: +<pre> + if( <i>expression </i> ) + <i>statement1 </i> ; +</pre> +In this case statement1 is evaluated if expression is true, otherwise +nothing is evaluated. +<p> +<b>Note for beginners: go back to our first example and make sure you + understand what if does.</b> +<p> +Another very simple control structure is the <tt>while</tt> statement: +<pre> + while( <i>expression </i> ) + <i>statement </i> ; +</pre> +This statement evaluates expression and if it is found to be true it +evaluates statement. After that it starts over and evaluates expression +again. This continues until expression is no longer true. This type of +control structure is called a <i>loop </i> and is fundamental to all +interesting programming. +<p> +<h2>Functions</h2> +Another control structure we have already seen is the function. +A function is simply a block of Pike code that can be executed with different arguments from different places in the program. +A function is declared like this: +<pre> + <i>modifers type name </i> ( <i>type name1 </i>, <i>type name2 </i>, <i>... </i> ) + { + <i> statements </i> + } +</pre> +The <i>modifiers </i> are optional. See section XX.XX for more details about +modifiers. The <i>type </i> specifies what kind of data the function returns. +For example, the word <tt>int</tt> would signify that the function returns +an integer number. The <i>name </i> is used to identify the function when +calling it. The names between the parenthesis are the arguments to the +function. They will be defined as local variabels inside the function. Each +variable will be declared to contain values of the preceeding type. +The three dots signifies that you can have anything from zero to 256 arguments +to a function. The <i> statements </i> between the brackets are the function +body. Those statements will be executed whenever the function is called. +<p> +<b>Example:</b> +<pre> + int sqr(int x) { return x*x; } +</pre> +This line defines a function called <tt>sqr</tt> to take one argument of the +type <tt>int</tt> and also return an <tt>int</tt>. The code itself returns +the argument multiplied by itself. To call this function somewhere in the code +you could simply put: <tt>sqr(17)</tt> and that would return the integer value +289. +<p> +As the example above shows that <tt>return</tt> is used to specify the +return value of a function. The value after <tt>return</tt> must be of the +type specified before the function name. If the function is specified to +return <tt>void</tt> nothing at all should be written after <tt>return</tt>. +Note that when a return statement is executed, the function will finish +immediately. Any statements following the return will be ignored. +<p> +There are many more control structures, they will all be described in a +later chapter devoted only to control structures. +<p> +<h2>True and false</h2> +Throughout this chapter the words <b>true</b> and <b>false</b> have been used +without any explanation to what they mean. Pike has a fairly simple way of +looking at this. The number 0 is false and everything else is true. +(Except when using operator overloading as I will discuss in a later chapter.) +<p> +<h2>Data Types</h2> +As you saw in our first examples we have to indicate the type of value returned by a functions or contained in a variable. We used integers (<tt>int</tt>.), strings (<tt>string</tt>), and arrays (with the * notation). +The others are <tt>mapping</tt>, <tt>mixed</tt>, <tt>void</tt>, <tt>float</tt>, <tt>multiset</tt>, <tt>function</tt>, <tt>object</tt> and <tt>program</tt>. +Neither <tt>mixed</tt> nor <tt>void</tt> are really types, <tt>void</tt> signifies that no value should be returned and <tt>mixed</tt> that the return value can be of any type, or that the variable can contain any type of value. +<tt>Function</tt>, <tt>object</tt> and <tt>program</tt> are all types related to object orientation. We will not discuss the last three in any great detail here, for more details, +in this short Pike overview. You can, however, read more at <a href=http://pike.infovav.se/>the pike home page</a>. There you'll also find more details on the other data types and the possible operations that are possible to perform on each of them. + +<dl> +<dt>Int +<dd>The integer type stores an integer. +<dt>Float +<dd>This variable type stores a floating point number. +<dt>Array +<dd>Arrays are basically a place to store a number of other values. Arrays in Pike are allocated blocks of values. They are dynamically allocated and do not need to be declared as in C. The values in the array can be set when creating the array like this, +<pre> + arr=({1,2,3}); +</pre> +or anytime afterwards like this, +<pre> + arr[index]=data; +</pre> +where index is an integer, i.e. entry number index is set to data. The first index of an array is 0 (zero). A negative index will count from the end of the array rather than from the beginning, -1 being the last element. +Note that arrays are shared and use reference counts to keep track of their references. This will have the effect that you can have two variables pointing at the same array, and when you change an index in it, both variables will reflect the change. +To indicate an array of a certain type of value you can use the * operator, e.g. +<pre> + string *i; +</pre> +which tells us that i is an array of strings. The * binds to the variable name, not to the type, so writing +<pre> + string *i, j; +</pre> +will declare one array of strings and one string. However, it's much clearer to write +<pre> + array (string) i; +</pre> + +<dt>String +<dd>A string contains a sequence of characters, a text, i.e. a word, a sentence, or a book. Note that this is not simply the letters A to Z; special characters, null characters, newlines and so on can all be stored in a string. Any 8-bit character is allowed. String is a basic type in Pike, as opposed to C where strings are represented by an array of char. This means that you cannot assign new values to individual characters in a string. +Also, all strings are "shared", i.e. if the same string is used in several places, only one will be stored in memory. +When writing a string in a program, you enclose it in doublequotes. To write special characters you need to use the following syntax; +<table> +<tr><td><li>\n</td><td>newline</td></tr> +<tr><td><li>\r</td><td>carriage return</td></tr> +<tr><td><li>\t</td><td>tab</td></tr> +<tr><td><li>\b</td><td>backspace</td></tr> +<tr><td><li>\"</td><td>" (quotation character)</td></tr> +<tr><td><li>\\</td><td>\ (literal backslash)</td></tr> +</table> +<dt>Mapping +<dd>A mapping is basically an array that can be indexed on any type, not just integers. It can also be seen as a way of linking data (usually strings) together. It consists of a lot of index-data pairs which are linked togeter in such a way that map[index1] returns data1. +A mapping can be created in a way similar to arrays; +<pre> + map=([five:good, ten:excellent]); +</pre> +You can also set that data by writing map[five]=good. +If you try to set an index in a mapping that isn't already present in the mapping it will be added as well. +<dt>Multiset +<dd>A multiset is basically a mapping without data values. When referring to an index of the multiset a 1 (one) will be returned if the index is present, 0 (zero) otherwise. +</dl> + +<HR NEWPAGE> +<H1>Chapter 2, A more elaborate example</h2> +To illustrate several of the fundamental points of Pike we will now introduce an example program, that will be extended as we go. We will build a database program that keeps track of a record collection and the songs on the records. +In the first version we hard-code our "database" into the program. The database is a mapping where the index is the record name and the data is an array of strings. The strings are of course the song names. The default register consists of one record. +<pre> + #!/usr/local/bin/pike + + mapping (string:array(string)) records = + ([ + "Star Wars Trilogy" : ({ + "Fox Fanfare", + "Main Title", + "Princess Leia's Theme", + "Here They Come", + "The Asteriod Field", + "Yoda's Theme", + "The Imperial March", + "Parade of the Ewoks", + "Luke and Leia", + "Fight with Tie Fighters", + "Jabba the Hut", + "Darth Vader's Death", + "The Forest Battle", + "Finale" + }) + ]); +</pre> +We want to be able to get a simple list of the records in our database. The function <tt>list_records</tt> just goes through the mapping <tt>records</tt> and puts the indices, i.e. the record names, in an array of strings, record_names. By using the builtin function <tt>sort</tt> we put the record names into the array in alphabetical order which might be a nice touch. +For the printout we just print a header, "Records:", followed by a newline. Then we use the loop control structure for to traverse the array and print every item in it, including the number of the record, by counting up from zero to the last item of the array. The builtin function sizeof gives the number of items in an array. The printout is formatted through the use of <tt>sprintf</tt> which works more or less like the C function of the same name. +<pre> + void list_records() + { + int i; + array (string) record_names=sort(indices(records)); + + write("Records:\n"); + for(i=0;i<sizeof(record_names);i++) + write(sprintf("%3d: %s\n", i+1, record_names[i])); + } +</pre> +If the command line contained a number our program will find the record of that number and print its name along with the songs of this record. First we create the same array of record names as in the previous function, then we find the name of the record whose number (num) we gave as an argument to this function. Next we put the songs of this record in the array <tt>songs</tt> and print the record name followed by the songs, each song on a separate line. +<pre> + void show_record(int num) + { + int i; + array (string) record_names = sort(indices (records)); + string name=record_names[num-1]; + array (string) songs=records[name]; + + write(sprintf("Record %d, %s\n",num,name)); + for(i=0;i<sizeof(songs);i++) + write(sprintf("%3d: %s\n", i+1, songs[i])); + } +</pre> +The main function doesn't do much; it checks whether there was anything on the command line after the invocation. If this is not the case it calls the list_records function, otherwise it sends the given argument to the show_record function. When either one of those functions is done the program just quits. +<pre> + int main(int argc, array (string) argv) + { + if(argc <= 1) + { + list_records(); + } else { + show_record((int) argv[1]); + } + } +</pre> +<h2>Taking care of input</h2> +Now, it would be better and more general if we could enter more records into our database. Let's add such a function and modify the <tt>main()</tt> function to accept "commands". +<p> +<h2>add_record()</h2> +Using the builtin function <tt>readline()</tt> we wait for input which will be put into the variable <tt>record_name</tt>. The argument to <tt>readline()</tt> is printed as a prompt in front of the user's input. Readline takes everything up to a newline character. +Now we use the control structure <tt>while</tt> to check whether we should continue inputting songs. The <tt>while(1)</tt> can be interpreted as "while everything is ok". When something has been read into the variable song it is checked. If it is a "." we return a null value that will be used in the while statement to indicate that it is not ok to continue asking for song names. If it is not a dot, the string will be added to the array of songs for this record, unless it's an empty string. +Note the <tt>+=</tt> operator. It is the same as saying +<tt>records[record_name]=records[record_name]+({song})</tt>. +<pre> + void add_record() + { + string record_name=readline("Record name: "); + records[record_name]=({}); + write("Input song names, one per line. End with '.' on it's own line.\n"); + while(1) + { + string song; + song=readline(sprintf("Song %2d: ", + sizeof(records[record_name])+1)); + if(song==".") + return; + if (strlen(song)) + records[record_name]+=({song}); + } + } +</pre> +<h2>main()</h2> +The main function now does not care about any command line arguments. Instead we use <tt>readline()</tt> to prompt the user for instructions and arguments. The available instructions are "add", "list" and "quit". What you enter into the variables cmd and args is checked in the <tt>switch()</tt> block. If you enter something that is not covered in any of the case statements the program just silently ignores it and asks for a new command. +In a <tt>switch()</tt> the argument (in this case cmd) is checked in the case statements. The first case where the expression equals cmd (the argument) then executes the statement after the colon. If no expression is equal, we just fall through without any action. +The only command that takes an argument is "list" which works like the first version of the program; if there is an argument that record is shown along with its songs, and if there isn't the program sends a list of the records in the database. When the program returns from either of the listing functions, the break instruction tells the program to jump out of the <tt>switch()</tt> block. +"Add" of course turns control over to the function descibed above. +If the command given is "quit" the <tt>exit(0)</tt> statement stops the execution of the program and returns 0 (zero) to the operating systems, telling it that everything was ok. +<pre> + int main(int argc, string * argv) + { + string cmd; + while(cmd=readline("Command: ")) + { + string args; + sscanf(cmd,"%s %s",cmd,args); + + switch(cmd) + { + case "list": + if((int)args) + { + show_record((int)args); + } else { + list_records(); + } + break; + + case "quit": + exit(0); + + case "add": + add_record(); + break; + } + } + } +</pre> + +<h2>Communicating with files</h2> +Now if we want to save the database and also be able to retrieve previously stored data we have to communicate with the environment, i.e. with files on disk. +Now we have to introduce objects. To open a file, be it for writing or for reading, we need to use the builtin program <tt>File</tt>. +A program is a data type which contains code, function and variables. +A program can be <i>cloned</i>, i.e. we can create an data area for the program and initialize it with the physical file in question. The methods and variables in the file object enables us to perform actions on the associated file. +The methods we need to use are open, read, write and close. See chapter +XXXX for more details. +<p> +<h2>save()</h2> +First we clone a <tt>File</tt> program to the object <tt>o</tt>. Then we use it to open the file named file for writing, using the fact that if there's an error during opening, o will return a false value which we can detect and act upon by exiting. The arrow operator is what you use to access methods and variables in an object. +If there's no error we use yet another control structure, <tt>foreach</tt>, to go through the mapping records one record at a time. We precede record names with the string "Record: " and song names with "Song: ". We also put every entry, be it song or record, on its own line by adding a newline to everything we write to the file.<br> +Finally, remember to close the file. +<pre> + void save(string file) + { + string name, song; + object o; + o=File(); + + if(!o->open(file,"wct")) + { + write("Failed to open file.\n"); + return; + } + + foreach(indices(records),name) + { + o->write("Record: "+name+"\n"); + foreach(records[name],song) + o->write("Song: "+song+"\n"); + } + + o->close(); + } +</pre> +<p> +<h2>load()</h2> +The <tt>load</tt> function begins much the same, except we open the file named <tt>file</tt> for reading instead. +When receiving data from the file we put it in the string <tt>file_contents</tt>. +The abscense of arguments to the method o->read means that the reading should not end until the end of the file. +After having closed the file we initialise our database, i.e. the mapping records. Then we have to put <tt>file_contents</tt> into the mapping and we do this by splitting the string on newlines (cf. the split operator in Perl) using the division operator. Yes, that's right: by dividing one string with another we can obtain an array consisting of parts from the first. And by using a <tt>foreach</tt> statement we can take the string <tt>file_contents</tt> apart piece by piece, putting each piece back in its proper place in the mapping records. +<pre> + void load(string file) + { + object o; + string name="ERROR"; + string file_contents,line; + + o=File(); + if(!o->open(file,"r")) + { + write("Failed to open file.\n"); + return; + } + + file_contents=o->read(); + o->close(); + + records=([]); + + foreach(file_contents/"\n",line) + { + string cmd, arg; + if(sscanf(line,"%s: %s",cmd,arg)) + { + switch(lower_case(cmd)) + { + case "record": + name=arg; + records[name]=({}); + break; + + case "song": + records[name]+=({arg}); + break; + } + } + } + } +</pre> +<h2>main() revisited</h2> +<tt>main()</tt> remains almost unchanged, except for the addition of two case statements with which we now can call the load and save functions. Note that you must provide a filename to load and save, respectively, otherwise they will return an error which will crash the program. +<pre> + case "save": + save(args); + break; + + case "load": + load(args); + break; +</pre> +<p> +<h2>Completing the program</h2> +Now let's add the last functions we need to make this program useful: the ability to delete entries and search for songs. +<p> +<h2>delete()</h2> +If you sell one of your records it might be nice to able to delete that entry from the database. The delete function is quite simple; first we set up an array of record names (cf. the <tt>list_records</tt> function). Then we find the name of the record of the number num and use the builtin function <tt>m_delete()</tt> to remove that entry from <tt>records</tt>. +<pre> + void delete_record(int num) + { + string *record_names=sort(indices(records)); + string name=record_names[num-1]; + + m_delete(records,name); + } +</pre> +<h2>search()</h2> +Searching for songs is quite easy too. To count the number of <tt>hits</tt> we declare the variable hits. Note that it's not necessary to initialise variables, that is done automatically when the variable is declared if you do not do it explicitly. To be able to use the builtin function <tt>search()</tt>, which searches for the presence of a given string inside another, we put the search string in lowercase and compare it with the lowercase version of every song. The use of <tt>search()</tt> enables us to search for partial song titles as well. +When a match is found it is immediately written to standard output with the record name followed by the name of the song where the search string was found and a newline. +If there were no hits at all, the function prints out a message saying just that. +<pre> + void find_song(string title) + { + string name, song; + int hits; + + title=lower_case(title); + + foreach(indices(records),name) + { + foreach(records[name],song) + { + if(search(lower_case(song), title) != -1) + { + write(name+"; "+song+"\n"); + hits++; + } + } + } + + if(!hits) write("Not found.\n"); + } +</pre> +<h2>main() again</h2> +Once again <tt>main()</tt> is left unchanged, except for yet another two case statements used to call the <tt>search()</tt> and <tt>delete</tt> functions, respectively. Note that you must provide an argument to delete or it will not work properly. +<pre> + case "delete": + delete_record((int)args); + break; + + case "search": + find_song(args); + break; +</pre> +<h2>Then what?</h2> +Well that's it! The example is now a complete working example of a Pike program. But of course there are plenty of details that we haven't attended to. Error checking is for example extremely sparse in our program. This is left for you +to do as you continue to reed this book. Tthe complete listing of this example can be found in APPENDIX B on page XXX. Read it, study it and enjoy! +<p> + +<table cellpadding=10 width="100%" border=1 cellspacing=0> +<tr><td> +<H2>Simple exercises</H2> +<ul> +<li> Make a program which writes hello world 10 times. +<li> Modify hello_world.pike to write the first argument to the program. +<li> Make a program that writes a hello_world program to stdout + when executed. +<li> Modify the register program to store data about programs and diskettes + instead of songs and records. +<li> Add code to the register program that checks that the user typed + an argument when required. The program should notify the user and + wait to receive more commands instead of exiting with an error message. +<li> Add code to the register program to check that the arguments to + <tt>show_record</tt> and <tt>delete_records</tt> are numbers. Also + make sure that the number isn't less than one or bigger than the + available number of records. +<li> Rewrite the register program and put all the code in main(). +</ul> +</td></tr> +</table> + +<H1> 3. Control Structures </H1> +In this chapter all the control structures in Pike will be explained. As +mentioned earlier, control structures are used to control the flow of the +program execution. Note that functions that make the program pause and +simple function calls are not qualified as control structures. + +<h2>Conditions</h2> +Pike only has two major condition control structures. We have already seen +examples of both of them in Chapter two. But for completeness they will be +described again in this chapter. +<p> +<h2><tt>If</tt></h2> +The simplest one is called the <b>if statement</b>. It can be written anywhere +where a statement is expected and it looks like this: +<pre> + if ( <i>expression</i> ) + <i>statement1</i> ; + else + <i>statement2</i> ; +</pre> +Please note that there is no semicolon after the parenthesis or after the +<tt>else</tt>. Step by step, <tt>if</tt> does the following: +<ol> +<li><First it evaluates <i>expression</i>.<br> +<li>If the result was <b>false</b> go to point 5. +<li>Execute <i>statement1</i>. +<li>Jump to point 6. +<li>Execute <i>statement2</i>. +<li>Done. +</ol> + +This is actually more or less how the interpreter executes the if statement. +In short, <i>statement1</i> is executed if <i>expression</i> is <b>true</b> +otherwise <i>statement2</i> is executed. If you are not interested in +having something executed if the expression is false you can drop the +whole else part like this: +<pre> + if ( <i>expression</i> ) + <i>statement1</i> ; +</pre> +If on the other hand you are not interested in evaluating something if the +expression is <b>false</b> you should use the <b>not</b> operator to negate +the true/false value of the expression. See chapter 5 for more information +about the <b>not</b> operator. It would look like this: +<pre> + if ( ! <i>expression</i> ) + <i>statement2</i> ; +</pre> +Any of the statements here and in the rest of this chapter can +also be a <b>block</b> of statements. A block is a list of statements, +separated by semicolons and enclosed by brackets. Note that you should +never put a semicolon after a block of statements. The example above +would look like this; +<pre> + if ( ! <i>expression</i> ) + { + <i>statement</i> ; + <i>statement</i> ; + <i>statement</i> ; + } +</pre> + +<h2><tt>Switch</tt></h2> +A more sofisticated condition control structure is the <b>switch statement</b>. +A switch lets you select one of many choices depending on the value of an +expression and it can look something like this: +<pre> + switch ( <i>expression</i> ) + { + case <i>constant1</i>: + <i>expressions1</i> ; + break; + + case <i>constant2</i>: + <i>expressions2</i> ; + break; + + case <i>constant3</i> .. <i>constant4</i>: + <i>expressions3</i> ; + break; + + default: + <i>expressions5</i> ; + } +</pre> +As you can see, a switch statement is a bit more complicated than an +if statement. It is still fairly simple however. It starts by evaluating +the expression it then searches all the <tt>case</tt> statements in the +following block. If one is found to be equal to the value returned by +the expression, Pike will continue executing the code directly following +that <tt>case</tt> statement. When a <tt>break</tt> is encountered Pike +will skip the rest of the code in the switch block and continue executing +after the block. Note that it is not strictly nessesary to have a break +before the next case statement. If there is no break before the next case +statement Pike will simply continue executing and execute the code after +that case statement as well. +<p> +One of the case statements in the above example differs in that it is +a <b>range</b>. In this case, any value between <i>constant3</i> and +<i>constant4</i> will cause Pike to jump to <i>expressions3</i>. Note +that the ranges are inclusive, so the values <i>constant3</i> and +<i>constant4</i> are also valid. +<p> + +<h2>Loops</h2> +Loops are used to execute a piece of code more than once. Since this can +be done in quite a few different ways there are four different loop +control structures. They may all seem very similar, but using the right +one at the right time makes the code a lot shorter and simpler. + +<h2><tt>while</tt></h2> +<tt>While</tt> is the simplest of the loop control structures. It looks +just like an <tt>if</tt> statement without the else part: +<pre> + while ( <i>expression</i> ) + <i>statement</i> ; +</pre> +The differance in how it works isn't that big either, the statement is +executed if the expression is true. Then the expression is evaluated +again, and if it is true the statement is executed again. Then it +evaluates the expression again and so forth... Here is an example of +how it could be used: +<pre> + int e=1; + while(e<5) + { + show_record(e); + e=e+1; + } +</pre> +This would call show_record with the values 1, 2, 3 and 4. +<p> +<h2><tt>for</tt></h2> +<tt>For</tt> is simply an extention of <tt>while</tt> it provides an +even shorter and more compact way of writing loops. The syntax looks +like this: +<pre> + for ( <i>initalizer statement</i> ; <i>expression</i> ; <i>incrementor expression</i> ) + <i>statement</i> ; +</pre> +For does the following steps: +<ol> +<li> Executes the the <i>initalizer statement</i>. The initializer statement + is executed only once and is most commonly used to initalize the loop + variable. +<li> Evaluates <i>expression</i> +<li> If the result was false it exits the loop and continues with the + program after the loop. +<li> Executes <i>statement</i>. +<li> Executes the <i>incrementor expression</i>. +<li> Starts over from 2. +</ol> +This means that the example in the while section can be written like this: +<pre> + for(int e=1; e<5; e=e+1) + show_record(e); +</pre> +<p> + +<h2><tt>do-while</tt></h2> +Sometimes it is unpractical that the expression is always evaluated before +the first time the loop is executed. Quite often you want to execute +something, and then do it over and over until some condition is satisfied. +This is exactly when you should use the do-while statement. +<pre> + do + <i>statement</i> ; + while ( <i>expression</i> ); +</pre> +As usual, the <i>statement</i> can also be a block of statements, and then +you do not need a semicolon after it. To clarify, this statement executes +<i>statement</i> first, and then evaluates the <i>expression</i>. If the +expression is <b>true</b> it executes the loop again. For instance, if you +want to make a program that lets your modem dial your internet provider, +it could look something like this: +<!-- Can someone come up with a better example? --> +<pre> + do { + modem->write("ATDT441-9109\n"); // Dial 441-9109 + } while(modem->gets()[..6]] == "CONNECT"); +</pre> +This example assumes you have written something that can communicate with +the modem by using the functions <tt>write</tt> and <tt>gets</tt>. +<p> +<h2><tt>foreach</tt></h2> +<tt>Foreach</tt> is unique in that it does not have an explicit test expression +evaluated for each iteration in the loop. Instead, <tt>foreach</tt> executes +the statement once for each element in an array. <tt>Foreach</tt> looks like +this: +<pre> + foreach ( <i>array expression</i>, <i>variable</i> ) + <i>statement</i> ; +</pre> +We have already seen an example of <tt>foreach</tt> in the <tt>find_song</tt> +function in chapter 2. What foreach does is: +<ol> +<li> It evaluates the <i>array expression</i> which must return an array. +<li> It then assigns the first element from the array to the <i>variable</i>. +<li> Then it executes the <i>statement</i>. +<li> If there are more elements in the array, the next one is assigned to + the <i>variable</i>, otherwise exit the loop. +<li> Go to point 3. +</ol> +<tt>Foreach</tt> is not really nessesary, but it is faster and clearer than +doing the same thing with a <tt>for</tt> loop, as shown here: +<pre> + array tmp1= <i>array expression</i> ; + for ( tmp2 = 0; tmp2 < sizeof(tmp1); tmp2++ ) + { + <i>variable</i> = tmp1 [ tmp2 ]; + <i>statement</i> ; + } +</pre> +<p> + +<h2>Breaking out of loops</h2> +The loop control structures above are enough to solve any problem, but +they are not enough to provide an easy solution to all problems. One thing +that is still missing is the ability to exit a loop in the middle of it. +There are three ways to do this: + +<h2><tt>break</tt></h2> +Break exits a loop or switch statement immediately and continues +executing after the loop. Break can not be used outside of a loop or +switch. It is quite useful in conjunction with <tt>while(1)</tt> to +construct command parsing loops for instance: +<pre> + while(1) + { + string command=readline("> "); + if(command=="quit") break; + do_command(command); + } +</pre> +<p> +<h2><tt>continue</tt></h2> +Continue does almost the same thing as <tt>break</tt>, except instead of +breaking out of the loop it only breaks out of the loop body. It then continues +to execute the next iteration in the loop. For a <tt>while</tt> loop, this +means it jumps up to the top again. For a <tt>for</tt> loop, it jumps to the +incrementor expression. For a <tt>do-while</tt> loop it jumps down to the +expression at the end. To continue our example above, continue can be used +like this: +<pre> + while(1) + { + string command=readline("> "); + if(strlen(command) == 0) continue; + if(command=="quit") break; + do_command(command); + } +</pre> +This way, <tt>do_command</tt> will never be called with an empty string as +argument. +<p> +<h2><tt>return</tt></h2> +Return doesn't just exit the loop, it exits the whole function. We have seen +several examples how how to use it chapter 2. None of the functions in chapter +two returned anything in particular however. To do that you just put the return +value right after the <tt>return</tt>. Of course the type of the return value +must match the type in the function declaration. If your function declaration +is <tt>int main()</tt> the value after the return must be an <b>int</b>. +For instace, if we wanted to make a program that always returns an error +code to the system, just like the UNIX command <tt>false</tt> this is how +it would be done: +<pre> + #!/usr/local/bin/pike + + int main() + { + return 1; + } +</pre> +This would return the error code <tt>1</tt> to the system when the program +is runned. +<p> +<table cellpadding=10 width="100%" border=1 cellspacing=0> +<tr><td> +<H2>Exercises</H2> +<ul> +<li> End all functions in the examples in chapter two with a return statement. +<li> Change all <tt>foreach</tt> loops to <tt>for</tt> or <tt>while</tt> loops. +<li> Make the <tt>find_song</tt> function in chapter 2 return when the first + matching song is found. +<li> Make the <tt>find_song</tt> function write the number of the record + the song is on. +<li> If you failed to get the program to work properly in the last exercise + of chapter 2, try it again now. +<li> Make a program that writes all the numbers from 1 to 1000. +<li> Modify the program in the previous exercise to NOT write numbers dividable by 3, 7 or 17. +<li> Make a program that writes all the prime numbers between 1 to 1000. +</ul> +</td></tr> +</table> + +<p> +<HR NEWPAGE> +<H1> 4. Data types </h1> +In this chapter we will discuss all the different ways to store data +in Pike in detail. We have seen examples of many of these, but we haven't +really gone into how they work. In this chapter we will also see which +operators and functions work with the different types. +There are two categories of data types in Pike: <b>atomic types</b>, and +<b>pointer types</b>. The differance is that atomic types are copied when +assigned to variable. With pointer types, merely the pointer is copied, +that way you get two variables pointing to the same thing. +<p> + +<h2>Basic types</h2> +The basic types are <tt>int</tt>, <tt>float</tt> and <tt>string</tt>. +For you who are accustomed to C or C++, it may seem odd that a string +is a basic type as opposed to an array of char, but it is surprisingly +easy to get used to. + +<h2><tt>int</tt></h2> +<tt>Int</tt> is short for integer, or integer number. They are normally +32 bit integers, which means that they are in the range -2147483648 to +2147483647. Note that on some machines an <tt>int</tt> might be larger +than 32 bits. Since they are integers, no decimals are allowed. An integer +constant can be written in several ways: +<pre> + 78 // decimal number + 0116 // octal number + 0x4e // hexadecimal number + 'N' // Ascii character +</pre> +All of the above represent the number 78. Octal notation means that +each digit is worth 8 times as much as the one after. Hexadecimal notation +means that each digit is wirth 16 times as much as the one after. +Hexadecimal notation uses the letters a, b, c, d, e and f to represent the +numbers 10, 11, 12, 13, 14 and 15. The ASCII notation gives the ASCII +value of the character between the single quotes. In this case the character +is <tt>N</tt> which just happen to be 78 in ASCII. +<p> +All the arithmetic, bitwise and comparison operators can be used on integers. +Also note these functions: +<dl> +<dt><tt>int intp(mixed <i>x</i>)</tt> +<dd> This function returns 1 if <i>x</i> is an int, 0 otherwise. +<dt><tt>int random(int <i>x</i>)</tt> +<dd>This function returns a random number greater or equal to zero and smaller than <i>x</i>. +<dt><tt>int reverse(int <i>x</i>)</tt> +<dd>This function reverses the order of the bits in <i>x</i> and returns the new number. It is not very useful. +<dt><tt>int sqrt(int <i>x</i>)</tt> +<dd>This computes the square root of <i>x</i>. The value is always rounded down. +</dl> +<h2><tt>float</tt></h2> +Although most programs only use ingegers, they are unpractical when doing +trigonometric caluculations, transformations or anything else where you +need decimals. For this purpose you use <tt>float</tt>. Floats are normally +32 bit floating point numbers, which means that they can represent very large +and very small numbers, but only with 9 accurate digits. To write a floating +point constant, you just put in the decimals or write it in the exponential +form: +<pre> + 3.14159265358979323846264338327950288419716939937510 // Pi + 1.0e9 // A billion + 1.0e-9 // A billionth +</pre> +Of course you do not need this many decimals, but it doesn't hurt either. +Usually digits after the nineth digit are ignored, but on some architechtures +<tt>float</tt> might have higher accuracy than that. In the exponential form, +<tt>e</tt> means "times 10 to the power of", so <tt>1.0e9</tt> is equal to +"1.0 times 10 to the power of 9". +<p> +All the arithmetic and comparison operators can be used on floats. +Also, these functions operates on floats: +<dl> +<dt>trigonometric functions +<dd> The trigonometric functions are: <tt>sin</tt>, <tt>asin</tt>, + <tt>cos</tt>, <tt>acos</tt>, <tt>tan</tt> and <tt>atan</tt>. + If you do not know what these functions do you probably don't + need them. + +<dt><tt>float log(float <i>x</i>)</tt> +<dd>This function computes the natural logarithm of <i>x</i>, + +<dt><tt>float exp(float <i>x</i>)</tt> +<dd>This function computes <b>e</b> raised to the power of <i>x</i>. + +<dt><tt>float pow(float <i>x</i>, float <i>y</i>)</tt> +<dd>This function computes <i>x</i> raised to the power of <i>y</i>. + +<dt><tt>float sqrt(float <i>x</i>)</tt> +<dd>This computes the square root of <i>x</i>. + +<dt><tt>float floor(float <i>x</i>)</tt> +<dd>This function computes the highest integer value lower or equal to <i>x</i>. + +<dt><tt>float ciel(float <i>x</i>)</tt>, +<dd>This function computes the lowest integer value higher or equal to <i>x</i>. +</dl> + +<h2><tt>string</tt></h2> +A <tt>string</tt> can be seen as an array of values from 0 to 255. +Usually a string contains text such as a word, a sentence, a page or +even a whole book. But it can also contain parts of a binary file, +compressed data or other binary data. Strings in Pike are <b>shared</b>, +which means that identical strings share the same memory space. This +reduces memory usage very much for most applicatoins and also speeds +up string comparisons. We have already seen how to write a constant +string: +<pre> + "hello world" // hello world + "\116" // N (116 is the octal ASCII value for N) + "\t" // A tab character + "\n" // A newline character + "\r" // A carriage return character + "\b" // A backspace character + "\0" // A null character + "\"" // A doublequote character + "\\" // A singe backslash + "hello world\116\t\n\r\b\0\"\\" // All of the above +</pre> +As you can see, any sequence of characters within double quotes is a string. +The backslash character is used to escape characters that are not allowed or +impossible to type. As you can see, <tt>\t</tt> is the sequence to produce +a tab character, <tt>\\</tt> is used when you want one backslash and +<tt>\"</tt> is used when you want a doublequote to be a part of the string +instead of ending it. Also, <tt>\<i>XXX</i></tt> where <i>XXX</i> is an +octal number from 000 to 377 lets you write any character you want in the +string, even null characters. +<p> +Although a string is an array, you can not change the individual characters in the string. Instead you have to construct a new string, here is an example +of how: +<pre> + string s = "hello torld"; + s=s[..5]+"w"+s[7..]; +</pre> +<p> +All the comparison operators plus those listed here can be used on strings: +<dl> +<dt> Summation +<dd> Adding strings together will simply concatenate them. + <tt>"foo"+"bar"</tt> becomes <tt>"foobar"</tt>. +<dt> Subtraction +<dd> Subtracting one string from another will remove all occurances + of the second string from the first one. So + <tt>"foobarfoogazonk" - "foo"</tt> results in <tt>"bargazonk"</tt>. +<dt> Indexing +<dd> Indexing will let you get the ascii value of any character in a string. + The first character is index zero. +<dt> Range +<dd> The range operator will let you copy any part of the string into a + new string. +<dt> Division +<dd> Divison will let you divide a string at every occurance of a word or + character. For instance if you do <tt>"foobargazonk" / "o"</tt> the + result would be <tt>({"f","","bargaz","nk"})</tt>. +<dt> Multiplication +<dd> The opposit of the division operator can be accoplished by multiplying + an array with a string. So if you evaluate + <tt>({"f","","bargaz","nk"}) * "o"</tt> the result would be + <tt>"foobargazonk"</tt>. +</dl> +<p> +Also, these functions operates on strings: +<dl> +<dt><tt>string capitalize(string <i>s</i>)</tt> +<dd>Returns <i>s</i> with the first character converted to upper case. + +<dt><tt>string lower_case(string <i>s</i>)</tt> +<dd>Returns <i>s</i> with all the upper case characters converted to lower case. + +<dt><tt>string replace(string <i>s</i>, string <i>from</i>, string <i>to</i>)</tt> +<dd>This function replaces all occurances of the string <i>from</i> in <i>s</i> with <i>to</i> and returns the new string. + +<dt><tt>string reverse(string <i>s</i>)</tt> +<dd>This function returns a copy of <i>s</s> with the last byte from <i>s</i> + first, the second last in second place and so on. + +<dt><tt>string search(string <i>haystack</i>, string <i>needle</i>)</tt> +<dd>This function finds the first occurance of <i>needle</i> in <i>haystack</i>. + +<dt><tt>string sizeof(string <i>s</i>)</tt> +<dd>Same as <tt>strlen(<i>s</i>)</tt>, returns the length of the string. + +<dt><tt>int stringp(mixed <i>s</i>)</tt> +<dd>This function returns 1 if <i>s</i> is a string, 0 otherwise. + +<dt><tt>string strlen(string <i>s</i>)</tt> +<dd>Returns the length of the string <i>s</i>. + +<dt><tt>string upper_case(string <i>s</i>)</tt> +<dd>This function returns <i>s</i> with all lower case characters converted + to upper case. +</dl> + + +<h2>Pointer types</h2> +The basic types are, as the name implies, very basic. They are foundation, +most of the pointer types are merely interesting ways to store the basic +types. The pointer types are <tt>array</tt>, <tt>mapping</tt>, +<tt>multiset</tt>, <tt>program</tt>, <tt>object</tt> and <tt>function</tt>. +They are all <b>pointers</b> which means that they point to an something +in memory. This "something" is freed when there are no more pointers to it. +Assigning a variable with a value of a pointer type will not copy this +"something" instead it will only generate a new reference to it. Special care +sometimes has to be taken when giving one of these types as arguments to +a function; the function can in fact modify the "something". If this effect +is not wanted you have to explicitly copy the value. More about this will +be explained later in this chapter. + +<h2><tt>array</tt></h2> +Arrays are the simplest of the pointer types. An array is merely a block of +memory with a fixed size containing a number of slots which can hold any +type of value. These slots are called <b>elements</b> and are accessible +through the index operator. To write a constant array you enclose the +values you want in the array with <tt>({ })</tt> like this: +<pre> + ({ }) // Empty array + ({ 1 }) // Array containing one element of type int + ({ "" }) // Array containing a string + ({ "", 1, 3.0 }) // Array of three elements, each of different types +</pre> +As you can see, each element in the array can contain any type of value. +Indexing and ranges on arrays works just like on strings, except with +arrays you can change values inside the array with the index operator. +However, there is no way to change the size of the array, so if you want +to append values to the end you still have to add it to another array +which creates a new array. Figure 4.1 shows how the schematics of an array. +As you can see, it is a very simple memory structure. +<p> +<center> +<img src=array.gif><br> +fig 4.1 +</center> +<p> +Operators and functions usable with arrays: +<dl> +<dt> indexing ( <tt><i>arr</i> [ <i>c</i> ]</tt> ) +<dd> Indexing an array retreives or sets a given element in the array. + The index <i>c</i> has to be an integer. To set an index, simply put + the whole thing on the left side of an assignment, like this: + <tt><i>arr</i> [ <i>c</i> ] = <i>new_value</i></tt> + +<dt> range ( <tt><i>arr</i> [ <i>from</i> .. <i>to</i> ]</tt> ) +<dd> The range copies the elements <i>from</i>, <i>from</i>+1, , <i>from</i>+2 ... <i>to</i> into a new array. The new array will have the size <i>to</i>-<i>from</i>-1. + +<dt> comparing (<tt><i>a</i> == <i>b</i></tt> and <tt><i>a</i> != <i>b</i></tt>) +<dd> The equal operator returns 1 if <i>a</i> and <i>b</i> are the <b>same</b> arrays. It is not enough that they have the same size and same data. They must + be the same array. For example: <tt>({1}) == ({1})</tt> would return 0, while +<tt>array(int) a=({1}); return a==a;</tt> would return 1. Note that you cannot +use the operators <tt>></tt>, <tt>>=</tt>, <tt><</tt> or <tt><=</tt> on arrays. + +<dt> Summation (<tt><i>a</i> + <i>b</i></tt>) +<dd> As with strings, summation concatenates arrays. <tt>({1})+({2})</tt> returns <tt>({1,2})</tt>. + +<dt> Subtractions (<tt><i>a</i> - <i>b</i></tt>) +<dd> Subtracting one array from another returns an array returns a copy of + <i>a</i> with all the elements that are also present in <i>b</i> removed. + So <tt>({1,3,8,3,2}) - ({3,1})</tt> returns <tt>({8,2})</tt>. + +<dt> Intersection (<tt><i>a</i> & <i>b</i></tt>) +<dd> Intersection returns an array with all values that are present in both + <i>a</i> and <i>b</i>. The order of the elements will be the same as + the the order of the elements in <i>a</i>. Example: + <tt>({1,3,7,9,11,12}) & ({4,11,8,9,1})</tt> will return: + <tt>({1,9,11})</tt>. + +<dt> Union (<tt><i>a</i> | <i>b</i></tt>) +<dd> Union works almost as summation, but it only concatenates elements not + already present in <i>a</i>. So, <tt>({1,2,3}) | ({1,3,5})</tt> will + return <tt>({1,2,3,5})</tt>. + +<dt> Xor (<tt><i>a</i> ^ <i>b</i></tt>) +<dd> This is also called symmetric differance. It returns an array with all + elements present in <i>a</i> or <i>b</i> but the element must NOT + be present in both. Example: <tt>({1,3,5,6}) ^ ({4,5,6,7})</tt> will + return <tt>({1,3,4,7})</tt>. + +<dt><tt>array aggregate(mixed ... <i>elems</i>)</tt> +<dd> This function does the same as the <tt>({ })</tt> operator; it creates an + array from all arguments given to it. In fact, writing <tt>({1,2,3})</tt> + is the same as writing <tt>aggregate(1,2,3)</tt>. + +<dt><tt>array allocate(int <i>size</i>)</tt> +<dd>This function allocates a new array of size <tt>size</tt>. All the elements + in the new array will be zeroes. + +<dt><tt>int arrayp(mixed <i>a</i>)</tt> +<dd>This function returns 1 if <i>a</i> is an array, 0 otherwise. + +<dt><tt>array column(array(mixed) <i>a</i>, mixed <i>ind</i>)</tt> +<dd>This function goes through the array <i>a</i> and indexes every element + in it on <i>ind</i> and builds an array of the results. So if you have + an array <i>a</i> in which each element is a also an array. This function + will take a cross section, by picking out element <i>ind</i> from each + of the arrays in <i>a</i>. + +<dt><tt>int equal(mixed <i>a</i>, mixed <i>b</i>)</tt> +<dd> This function returns 1 if if <i>a</i> and <i>b</i> look the same. They + do not have to be pointers to the same array, as long as they are the same + size and containi equal data. + +<dt><tt>array filter(array <i>a</i>, mixed <i>func</i>, mixed ... <i>args</i>)</tt> +<dd> <tt>filter</tt> returns every element in <i>a</i> for which <i>func</i> returns <b>true</b> when called with that element as first argument, and <i>args</i> for the second, third, etc. arguments. + +<dt><tt>array map(array <i>a</i>, mixed <i>func</i>, mixed ... <i>args</i>)</tt> +<dd> This function works similar to <tt>filter</tt> but returns the results + of the function <i>func</i> instead of returning the elements from <i>a</i> for which <i>func</i> returns <b>true</b>. + +<dt><tt>array replace(array <i>a</i>, mixed <i>from</i>, mixed <i>to</i>)</tt> +<dd>This function will create a copy of <i>a</i> with all elements equal to + <i>from</i> replaced by <i>to</i>. + +<dt><tt>array reverse(array <i>a</i>)</tt> +<dd><tt>Reverse</tt> will create a copy of <i>a</i> with the last element first, the last but one second, and so on. + +<dt><tt>array rows(array <i>a</i>, array <i>indexes</i>)</tt> +<dd>This function is similar to <tt>column</tt>. It indexes <i>a</i> with + each element from <i>indexes</i> and returns the results in in an array. +For example: <tt>rows( ({"a","b","c"}), ({ 2,1,2,0}) ) </tt> will return +<tt>({"c","b","c","a"})</tt>. + +<dt><tt>array search(array <i>haystack</i>, mixed <i>needle</i>)</tt> +<dd>This function returns the first occurance of an element equal to + <i>needle</i> in the array <i>haystack</i>. + +<dt><tt>array sizeof(mixed <i>arr</i>)</tt> +<dd>This function returns the number of elements in the array <i>arr</i> + +<dt><tt>array sort(array <i>arr</i>, array ... <i>rest</i>)</tt> +<dd>This function sorts <i>arr</i> in smaller-to-larger order. Numbers, floats + and strings can be sorted. If there are any additional arguments, they + will be permutated in the same manner as <i>arr</i>. See page XXXX + for more details. + +<dt><tt>array uniq(array <i>a</i>)</tt> +<dd>This function returns a copy of the array <i>a</i> with all duplicate + elements removed. Note that that this function can return the elements + in any order. +</dl> +<p> +<h2><tt>mapping</tt></h2> +Mappings are are really just more generic arrays. However, they are slower +and use more memory than arrays, so they cannot replace arrays completely. +What makes mappings special is that they can be indexed on other things than +integers. We can imagine that a mapping looks like this: +<p> +<center> +<img src=mapping.gif><br> +fig 4.2 +</center> +<p> +Each index-value pair is floating around freely inside the mapping. There is +exactly one value for each index. We also have a (magical) lookup function. +This lookup function can find any index in the mapping very quickly. Now, if +the mapping is called <i>m</i> and we index it like this: +<tt><i>m</i> [ <i>i</i> ]</tt> the lookup function will quickly find the index +<i>i</i> in the mapping and return the corresponding value. If the index is +not found, zero is returned instead. +If we on the other hand assign an index in the mapping the value will +instead be overwritten with the new value. If the index is not found when +assigning, a new index-value pair will be added to the mapping. +Writing a constant mapping is easy: +<pre> + ([ ]) // Empty mapping + ([ 1:2 ]) // Mapping with one index-value pair, the 1 is the index + ([ "one":1, "two" ]) // Mapping which maps words to numbers + ([ 1:({2.0}), "":([]), ]) // Mapping with lots of different types +</pre> +<p> +As with arrays, mappings can contain any type. The main differance is that +the index can be any type too. Also note that the index-value pairs in a +mapping are not stored in a specific order. You can not refer to the +fourteenth key-index pair, since there is no way of telling which one is +the fourteenth. Because of this, you cannot use the range operator on +mappings. +<p> +The following operators and functions are important to use mappings: +<dl> +<dt> indexing ( <tt><i>m</i> [ <i>ind</i> ]</tt> ) +<dd> As discussed above, indexing is used to retreive, store and add values + to the mapping. +<dt> addition, subtraction, union, intersection and xor +<dd> All these operators works exactly as on arrays, with the differance that + they operate on the indexes. In those cases when the value can come from + either mapping, it will be taken from the right side of the operator. + This is to make it easier to add new values to a mapping with <tt>+=</tt>. + Some examples:<br> + <tt>([1:3, 3:1]) + ([2:5, 3:7])</tt> returns </tt>([1:3, 2:5, 3:7 ])</tt><br> + <tt>([1:3, 3:1]) - ([2:5, 3:7])</tt> returns </tt>([1:3])</tt><br> + <tt>([1:3, 3:1]) | ([2:5, 3:7])</tt> returns </tt>([1:3, 2:5, 3:7 ])</tt><br> + <tt>([1:3, 3:1]) & ([2:5, 3:7])</tt> returns </tt>([3:7])</tt><br> + <tt>([1:3, 3:1]) ^ ([2:5, 3:7])</tt> returns </tt>([1:3, 2:5])</tt><br> + +<dt> same ( <tt><i>a</i> == <i>b</i></tt> ) +<dd> Returns 1 if <i>a</i> is <b>the same</b> mapping as <i>b</i>, 0 otherwise. + +<dt> not same <tt><i>a</i> != <i>b</i></tt> ) +<dd> Returns 0 if <i>a</i> is <b>the same</b> mapping as <i>b</i>, 1 otherwise. + +<dt><tt>array indices(mapping <i>m</i>)</tt> +<dd><tt>Indices</tt> returns an array containing all the indexes in the mappin <i>m</i>. + +<dt><tt>void m_delete(mapping <i>m</i>, mixed <i>ind</i>)</tt> +<dd>This function removes the index-value pair with the index <i>ind</i> from the mapping <i>m</i>. + +<dt><tt>int mappingp(mixed <i>m</i>)</tt> +<dd>This function returns 1 if <i>m</i> is a mapping, 0 otherwise. + +<dt><tt>mapping mkmapping(array <i>ind</i>, array <i>val</i>)</tt> +<dd>This function constructs a mapping from the two arrays <i>ind</i> and + <i>val</i>. Element 0 in <i>ind</i> and element 0 in <i>val</i> becomes + one index-value pair. Element 1 in <i>ind</i> and element 1 in <i>val</i> + becomes another index-value pair, and so on.. + +<dt><tt>mapping replace(mapping <i>m</i>, mixed <i>from</i>, mixed <i>to</i>)</tt> +<dd>This function creates a copy of the mapping <i>m</i> with all values equal to <i>from</i> replaced by <i>to</i>. + +<dt><tt>mixed search(mapping <i>m</i>, mixed <i>val</i>)</tt> +<dd>This function returns the index of the 'first' index-value pair which has the value <i>val</i>. + +<dt><tt>int sizeof(mapping <i>m</i>)</tt> +<dd><tt>Sizeof</tt> returns how many index-value pairs there is in the mapping. + +<dt><tt>array values(mapping <i>m</i>)</tt> +<dd>This function does the same as <tt>indices</tt>, but returns an array with all the values instead. If <tt>indices</tt> and <tt>values</tt> are called on the same mapping after eachother, without any other mapping operations in between, the returned arrays will be in the same order. They can in turn be used as arguments to <tt>mkmapping</tt> to rebuild the mapping <i>m</i> again. + +<dt><tt>int zero_type(mixed t)</tt> +<dd>When indexing a mapping and the index is not found, zero is returned. However, problems can arise if you have also stored zeroes in the mapping. This function allows you to see the differance between the two cases. If <tt>zero_type(<i>m</i> [ <i>ind</i> ])</tt> returns 1, it means that the value was not present +in the mapping. If the value was present in the mapping, <tt>zero_type</tt> will return something else than 1. +</ul> +<p> +<h2><tt>multiset</tt></h2> +A multiset is almost the same thing as a mapping. The differance is that there +are no values: +<p> +<center> +<img src=multiset.gif><br> +fig 4.3 +</center> +<p> +Instead, the index operator will return 1 if the value was found +in the multiset and 0 if it was not. When assigning an index to a multiset like +this: <tt><i>mset</i>[ <i>ind</i> ] = <i>val</i></tt> the index <i>ind</i> +will be added to the multiset <i>mset</i> if <i>val</i> is <b>true</b>. +Otherwise <i>ind</i> will be removed from the multiset instead. +<p> +Writing a constant multiset is similar to writing an array: +<pre> + (< >) // Empty multiset + (< 17 >) // Multiset with one index: 17 + (< "", 1, 3.0, 1 >) // Multiset with 3 index +</pre> +Note that you can actually have two of the same index in a multiset. This is +normally not used, but can be practical at times. + +<h2><tt>program</tt></h2> +Normally, when we say <b>program</b> we mean something we can execute from +a shell prompt. However, Pike has another meaning for the same word. In Pike +a <tt>program</tt> is the same as a <b>class</b> in C++. A <tt>program</tt> +holds a table of what functions and variables are defined in that program. +It also holds the code itself, debug information and references to other +programs in the form of inherits. A <tt>program</tt> does not hold space +to store any data however. All the information in a <tt>program</tt> is +gathered when a file or string is run through the Pike compiler. The variable +space needed to execute the code in the program is stored in an <tt>object</tt> +which is the next data type we will discuss. +<p> +<center> + <img src=program.gif><br> +fig 4.4 +</center> +Writing a <tt>program</tt> is easy, in fact, every example we have tried so +far has been a <tt>program</tt>. Casting a string file name with a file name +in it will compile the file and return the resulting program. Note that if +the program was already compiled, the same program will be returned again. +There is also a way to write programs inside programs with the help of the +<tt>class</tt> keyword: +<pre> + class <i>class_name</i> { + <i>inherits, variables and functions </i> + } +</pre> +Writing a program like this can be used almost the same way as structs are +used in C. The <tt>class</tt> keyword can be written as a separate entity +outside of all functions, but it is also an expression which returns the +<tt>program</tt> written between the brackets. The <i>class_name</i> is +optinal. If used you can later refer to that <tt>program</tt> by the name +<i>class_name</i>. Let's look at an example: +<pre> + class record { + string title; + string artist; + array(string) songs; + } + + array(object(record)) records = ({}); + + void show_record(object(record) rec) + { + write("Record name: "+rec->title+"\n"); + write("Artist: "+rec->artist+"\n"); + write("Songs:\n"); + foreach(rec->songs, string song) + write(" "+song+"\n"); + } + + void add_empty_record() + { + records+=({ record() }); + } +</pre> +This could be a small part of a better record register program. It is not +a complete executable program in itself. In this example we create a +<tt>program</tt> called <tt>record</tt> which has three identifiers. +<tt>Show_record</tt> writes the contents of an object cloned from +<tt>record</tt>. In <tt>add_empty_record</tt> a new object is created +by calling <tt>record</tt>. +<p> + +<dl> +<dt> cloning +<dd> To create a data area for a <tt>program</tt> you need to instanciate or + <b>clone</b> the program. This is accomplished by using a pointer + to the <tt>program</tt> as if it was a function and call it. That + creates a new object and calls the function <tt>create</tt> in the + new object with the arguments. It is also possible to use the + functions <tt>new()</tt> and <tt>clone()</tt> which do exactly the + same thing except you can use a string to specify what program you + want to clone. +<dt> compiling +<dd> All programs are generated by compiling a file or a string. For this + purpose there are two functions: +<pre> + program compile_file(string <i>filename</i>); + program compile_string(string <i>p</i>, string <i>filename</i>); +</pre> + <tt>Compile_file</tt> simply reads the file given as argument, compiles + it and returns the resulting program. <tt>Compile_string</tt> instead + compiles whatever is in the string <i>p</i>. The second argument, + <i>filename</i>, is only used in debug printouts when an error occurs + in the newly made program. + +<dt> casting +<dd> Another way of compiling files to program is to use the <b>cast</b> + operator. Casting a string to the type <tt>program</tt> calls a function + in the master object which will compile the program in question for you. + The master also keeps the program in a cache, so if you later need the + same program again it will not be re-compiled. +<dt> <tt>int programp(mixed <i>p</i>)</tt> +<dd> This function returns 1 if <i>p</i> is a program, 0 otherwise. +<dt> comparisons +<dd> As with all data types <tt>==</tt> and <tt>!=</tt> can be used to + see if two programs are the same or not. +</dl> + +<p> +<h2><tt>object</tt></h2> +Although programs are absolutely nessesary for any application you might +want to write, they are not enough. A <tt>program</tt> doesn't have anywhere +to store data, it just merely outlines how to store data. To actually store +the data you need an <tt>object</tt>. Objects are basically a chunk of memory +with a reference to the program from which it was cloned. Many objects can +be made from one program. The <tt>program</tt> outlines where in the object +different variables are stored. +<center> + <img src=object.gif><br> +fig 4.5 +</center> +Each object has its own set of variables, and when calling a function in that +object, that function will operate on those variables. If we take a look at +the short example in the section about programs, we see that it would be +better to write it like this: +<pre> + class record { + string title; + string artist; + array(string) songs; + + void show_record() + { + write("Record name: "+title+"\n"); + write("Artist: "+artist+"\n"); + write("Songs:\n"); + foreach(rec->songs, string song) + write(" "+song+"\n"); + } + } + + array(object(record)) records = ({}); + + void add_empty_record() + { + records+=({ record() }); + } + + void show_record(object rec) + { + rec->show_record(); + } +</pre> +Here we can clearly see how the function <tt>show_record</tt> prints the +contents of the variables in that object. In essence, instead of accessing +the data in the object with the <tt>-></tt> operator, we call a function +in the object and have it write the information itself. This type of +programming is very flexible, since we can later change how <tt>record</tt> +stores it's data, but we do not have to change anything outside of +the <tt>record</tt> program. +<p> +Functions and operators relevant to objects: +<dl> +<dt> indexing +<dd> Objects can be indexed on strings access identifiers. If the identifier + is a variable, the value can also be set using indexing. If the identifier + is a function, a pointer to that function will be returned. If the + identifier is a constant, the value of that constant will be returned. + Note that the <tt>-></tt> operator is actually the same as indexing. + This means that <tt>o->foo</tt> is the same as to <tt>o["foo"]</tt> +<dt> cloning +<dd> As discussed in the section about programs, cloning a program can be done + in two different ways: + <ol> + <li> Use a pointer to the program as a function and call it. + <li> Use the functions <tt>new</tt> or <tt>clone</tt>. (They are the same function.) + </ol> + Whenever you clone an object, all the global variables will be + initailized. After that the function <tt>create</tt> will be called + with any arguments you call the program with. +<dt> <tt>void destruct(object <i>o</i>)</tt> +<dd> This function invalidates all references to the object <i>o</i> and + frees all variables in that object. This function is also called when + <i>o</i> runs out of references. If there is a function named + <tt>destroy</tt> in the object, it will be called before actually + destructing the object. +<dt> <tt>array(string) indices(object <i>o</i>)</tt> +<dd> This function returns a list of all identifiers in the object <i>o</i>. +<dt> <tt>program object_program(object <i>o</i>)</tt> +<dd> This function returns the program from which <i>o</i> was cloned. +<dt> <tt>int objectp(mixed <i>o</i>)</tt> +<dd> This function returns 1 if <i>o</i> is an object, 0 otherwise. + Note that if <i>o</i> has been destructed, this function will return 0. +<dt> <tt>object this_object()</tt> +<dd> This function returns the object in which the interpreter is currently + executing. +<dt> <tt>array values(object <i>o</i>)</tt> +<dd> This function returns the same as <tt>rows(o,indices(o))</tt>. + That means it returns the all the values of the identifiers in the + object <i>o</i>. +<dt> comparing +<dd> As with all data types <tt>==</tt> and <tt>!=</tt> can be used to + check if two objects are the same or not. +</dl> +<p> +<h2><tt>function</tt></h2> +When indexing an object on a string, and that string is the name of a function +in the object a <tt>function</tt> is returned. Despite is name, a +<tt>function</tt> is really a <b>function pointer</b>. +<center> + <img src=function.gif><br> +fig 4.6 +</center> +When the function pointer is called, the interpreter sets +<tt>this_object()</tt> to the object in which the function is located and +procedes to execute the function it points to. Also note that function pointers +can be passed around just like any other data type: +<pre> + int foo() { return 1; } + void bar() { return foo; } + void gazonk() { return foo(); } + void teleledningsanka() { return bar()(); } +</pre> +In this example, the function bar returns a pointer to the function +<tt>foo</tt>. No indexing is nessesary since the function <tt>foo</tt> is +located in the same object. The function <tt>gazonk</tt> simply calls +<tt>foo</tt>. However, note that the word <tt>foo</tt> in that function +is an expression returning a function pointer that is then called. To +further illustrate this, <tt>foo</tt> has been replaced by <tt>bar()</tt> +in the function <tt>teleledningsanka</tt>. +<p> +This is what you can do with a function pointer. +<dl> +<dt> calling ( <i>f</i> ( mixed ... <i>args</i> ) +<dd> As mentioned earlier, all function pointers can be called. In this example + the function <i>f</i> is called with the arguments <i>args</i>. + +<dt> <tt>string function_name(function <i>f</i>)</tt> +<dd> This function returns the name of the function <i>f</i> is pointing at. + +<dt> <tt>object function_object(function <i>f</i>)</tt> +<dd> This function returns the object the function <i>f</i> is located in. + +<dt> <tt>int functionp(mixed <i>f</i>)</tt> +<dd> This function returns 1 if <i>f</i> is a <tt>function</tt>, 0 otherwise. + If <i>f</i> is located in a destructed object, 0 is returned. + +<dt> <tt>function this_function()</tt> +<dd> This function returns a pointer to the function it is called from. + This is normally only used with <b>lambda</b> functions because they + do not have a name. +</dl> + +<p> +<HR NEWPAGE> +<H1>5. Operators</h1> +To make it easier to write Pike, and to make the code somewhat shorter, +some functions can be called with just one or two characters in the code. +These functions are called <b>operators</b> and we have already seen how +they work in plenty of examples. In this chapter I will describe in detail +what they do. The operators are divided into categories depending on their +function, but beware that some operators have meanings that go way beyond +the scope of the category they are in. + +<h2>Arithmetic operators</h2> +The arithmetic operators are the simplest ones, since they work just like +you remember from maths in school. The arithmetic operators are: +<center> +<p> +<table border=1> +<tr><th>Function</th> <th>Syntax</th> <th>Identifier</th> <th>Returns</th></tr> +<tr><td>Addition</td> <td>a + b</td> <td>`+</td> <td>the sum of a and b</td></tr> +<tr><td>Subtraction</td><td>a - b</td> <td>`-</td> <td>b subtracted from a</td></tr> +<tr><td>Negation</td> <td>- a</td> <td>`-</td> <td>minus a</td></tr> +<tr><td>Multiplication</td><td>a * b</td><td>`*</td> <td>a multiplied by b</td></tr> +<tr><td>Division</td> <td>a / b</td> <td>`/</td> <td>a divided by b</td></tr> +<tr><td>Modulo</td> <td>a % b</td> <td>`%</td> <td>the rest of a division between a and b</td></tr> +</table> +<p> +</center> + +When applied to integers or floats these operators do exactly what they +are supposed to do. The only operator in the list not known from basic +math is the <b>modulo</b> operator. The modulo operator returns the +rest of an integer division. It is the same as caluclating +<tt>a - floor(a / b) * b</tt>. <tt>floor</tt> rounds the value down to +closest lower integer value. Note that the call to <tt>floor</tt> isn't +needed when operating on integers, since dividing two integers will return +the result as an integer and it is always rounded down. For instance, +<tt>8 / 3</tt> would return <tt>2</tt>. +<p> +If all arguments to the operator are integers, the +result will also be an integer. If one is a float and the other is +an integer, the result will be a float. If both arguments are float, +the result will of course be a float. +<p> +However, there are more types in Pike than integers and floats. Here is +the complete list of combinations of types you can use with these operators: + +<center> +<table border=1> + +<tr> +<th>Operation</th><th>Returned type</th><th>Returned value</th> +</tr> + +<tr> +<td><tt><i>int</i> + <i>int</i></tt></td><td>int</td><td>the sum of the two values</td> +</tr> + +<tr> +<td><tt><i>float</i> + <i>int</i><br> + <i>int</i> + <i>float</i><br> + <i>float</i> + <i>float</i></tt></td><td>float</td><td>the sum of the two values</td> +</tr> + +<tr> +<td><i>string</i> + <i>string</i><br> + <i>int</i> + <i>string</i><br> + <i>float</i> + <i>string</i><br> + <i>string</i> + <i>int</i><br> + <i>string</i> + <i>float</i></tt></td><td>string</td><td>In this case, any int or float is first converted to a string. Then the two strings are concatenated and the resulting string is returned.</td> +</tr> + +<tr> +<td><tt><i>array</i> + <i>array</i></tt></td><td>array</td><td>The two arrays are concatenated into a new array and that new array is returned.</td> +</tr> + +<tr> +<td><tt><i>mapping</i> + <i>mapping</i></tt></td><td>mapping</td><td>A mapping with all the index-value pairs from both mappings is returned. If an index is present in both mappings the index-value pair from the right mapping will be used.</td> +</tr> + +<tr> +<td><tt><i>multiset</i> + <i>multiset</i></tt></td><td>multiset</td><td>A multiset with all the indices from both builtisets is returned.</td> +</tr> + +<tr> +<td><tt><i>int</i> - <i>int</i></tt></td><td>int</td><td>The right value subtracted from the left.</td> +</tr> + +<tr> +<td><tt><i>float</i> - <i>int</i><br> + <i>int</i> - <i>float</i><br> + <i>float</i> - <i>float</i></tt></td><td>float</td><td>The right value subtracted from the left.</td> +</tr> + +<tr> +<td><i>string</i> - <i>string</i></tt></td><td>string</td><td>A copy of the left string with all occurances of the right string removed.</td> +</tr> + +<tr> +<td><i>array</i> - <i>array</i></tt></td><td>array</td><td>A copy of the right array with all elements present in the right array removed. Example: <tt>({2,1,4,5,3,6,7}) - ({3,5,1})</tt> will return <tt>({2,4,6,7})</tt>.</td> +</tr> + +<tr> +<td><i>mapping</i> - <i>mapping</i></tt></td><td>mapping</td><td>A new mapping with all index-value pairs from the left mapping, except those indexes that are also present in the right mapping.</td> +</tr> + +<tr> +<td><i>multiset</i> - <i>multiset</i></tt></td><td>multiset</td><td>A copy of the left multiset without any index present in the left multiset.</td> +</tr> + +<tr> +<td>- <i>int</i></tt></td><td>int</td><td>Same as 0 - <i>int</i>.</td> +</tr> + +<tr> +<td>- <i>float</i></tt></td><td>float</td><td>Same as 0 - <i>float</i>.</td> +</tr> + +<tr> +<td><tt><i>int</i> * <i>int</i></tt></td><td>int</td><td>the product of the two values</td> +</tr> + +<tr> +<td><tt><i>float</i> * <i>int</i><br> + <i>int</i> * <i>float</i><br> + <i>float</i> * <i>float</i></tt></td><td>float</td><td>the product of the two values</td> +</tr> + +<tr> +<td><i>array(string)</i> * <i>string</i></tt></td><td>string</td><td>All the strings in the array are concatenated with the string on the right in between each string. Example: <tt>({"foo,"bar})*"-"</tt> will return <tt>"foo-bar".</tt></td> +</tr> + +<tr> +<td><tt><i>int</i> / <i>int</i></tt></td><td>int</td><td>The right integer divided by the left integer rounded towards zero.</td> +</tr> + +<tr> +<td><tt><i>float</i> . <i>int</i><br> + <i>int</i> / <i>float</i><br> + <i>float</i> / <i>float</i></tt></td><td>float</td><td>The right value diveded by the left value.</td> +</tr> + +<tr> +<td><tt><i>string</i> / <i>string</i></tt></td><td>array(string)</td><td>In symmetry with the multiplication operator, the division operator can split a string into pieces. The right string will be split at every occurance of the right string and an array containing the results will be returned. Example: +<tt>"foo-bar"/"-"</tt> will return <tt>({"foo","bar"})</tt></td> +</tr> + +<tr> +<td><tt><i>int</i> % <i>int</i></tt></td><td>int</td><td>The rest of a division. If <tt>a</tt> and <tt>b</tt> are integers, <tt>a%b</tt> is the same as <tt>a-(a/b)*b</tt></td> +</tr> + +<tr> +<td><tt> +<i>float</i> % <i>float</i><br> +<i>int</i> % <i>float</i><br> +<i>float</i> % <i>int</i></tt></td><td>float</td><td>The rest of a division. If <tt>a</tt> and <tt>b</tt> are floats, <tt>a%b</tt> is the same as <tt>a-floor(a/b)*b</tt></td> +</tr> + + + +</table> +</center> + +<h2>Comparing operators</h2> +The arithmetic operators would be hard to use for something interesting +without the ability to compare them to each other. For this purpose there +are six comparison operators: + +<center> +<p> +<table border=1> +<tr><th>Function</th> <th>Syntax</th> <th>Identifier</th> <th>Returns</th></tr> +<tr><td>Same</td> <td>a == b</td> <td>`==</td> <td>1 if a is the same value as b, 0 otherwise</td></tr> +<tr><td>Not same</td> <td>a != b</td> <td>`!=</td> <td>0 if a is the same value as b, 1 otherwise</td></tr> +<tr><td>Greater than</td> <td>a > b</td> <td>`> </td><td>1 if a is greater than b, 0 otherwise</td></tr> +<tr><td>Greater than or equal to</td><td>a >= b</td><td>`>=</td><td>1 if a is greater to or equal to b, 0 otherwise</td></tr> +<tr><td>Lesser than</td> <td>a < b</td> <td>`< </td><td>1 if a is lesser than b, 0 otherwise</td></tr> +<tr><td>Lesser than or equal to</td> <td>a <= b</td><td>`<=</td><td>1 if a is lesser than or equal to b, 0 otherwise</td></tr> +</table> +<p> +</center> + +The <tt>==</tt> and <tt>!=</tt> operators can be used on any type. For two +values to be <b>same</b> they must be the same type. Therefor 1 and 1.0 are +not <b>same</b>. Also, for two values of <b>pointer types</b> to be the same +the two values must be pointers to the same object. It is not enough that +the two objects are of the same size and contain the same data. +<p> +The other operators in the table above can only be used with integers, floats +and strings. If you compare an integer with a float, the int will be promoted +to a float before the comparison. When comparing strings, lexical order is +used and the value of the environment variables <tt>LC_CTYPE</tt> and +<tt>LC_LANG</tt> is respected. +<p> + +<h2>Logical operators</h2> +Logical operators are operators that operate with truth values. In Pike any value +except zero is considered <b>true</b>. Logical operators are a very basic part +of Pike. They can also decide which arguments to evaluate and which not to +evaluate. Becuase of this the logical operators do not have any identifiers and +can not be called as normal functions. There are four logical operators: + +<center> +<p> +<table border=1> +<tr><th>Function</th> <th>Syntax</th> <th>Returns</th></tr> +<tr><td>And</td> <td>a && b</td> <td>If a is false, a is returned and b is not evaluated. Otherwise, b is returned.</td></tr> +<tr><td>Or</td> <td>a || b</td> <td>If a is true, a is returned and b is not evaluated. Otherwise, b is returned.</td></tr> +<tr><td>Not</td> <td>! a</td> <td>Returns 0 if a is true, 1 otherwise.</td></tr> +<tr><td>If-else</td> <td>a ? b : c</td> <td>If a is true, b is returned and c is not evaluated. Otherwise c is returned and a is not evaluated.</td></tr> +</table> +<p> +</center> + +<h2>Bitwise/set operators</h2> +These operators are used to manipulate bits as members in sets. +They can also manipulate arrays, multisets and mappings as sets. + +<center> +<p> +<table border=1> +<tr><th>Function</th> <th>Syntax</th> <th>Identifier</th> <th>Returns</th></tr> +<tr><td>Shift left</td> <td>a << b</td> <td>`<<</td> <td>Multiplies a by 2 b times.</td></tr> +<tr><td>Shift right</td> <td>a >> b</td> <td>`>></td> <td>Divides a by 2 b times.</td></tr> +<tr><td>Inverse (not)</td> <td>~ a</td> <td>`~</td> <td>Returns -1-a.</td></tr> +<tr><td>Intersection (and)</td> <td>a & b</td> <td>`&</td> <td>All elements present in both a and b.</td></tr> +<tr><td>Union (or)</td> <td>a | b</td> <td>`|</td> <td>All elements present in a or b.</td></tr> +<tr><td>Symmetric differance (xor)</td><td>a ^ b</td> <td>`^</td> <td>All elements present in a or b, but not present in both.</td></tr> +</table> +<p> +</center> + +The first three operators can only be used with integers and should be +pretty obvious. + +The other three, intersection, union and symmetric differance, can be used with +integers, arrays, multisets and mappings. When used with integers, these +operators considers each bit in the integer a separate element. If you do +not know about how bits in integers I suggest you go look it up in some other +programming book or just don't use these operators on integers. +<p> +When intersection, union or symmetric differance is used on an array each element +in the array is considered by itself. So intersecting two arrays will result +in an array with all elements that are present in both arrays. Example: +<tt>({7,6,4,3,2,1}) & ({1, 23, 5, 4, 7})</tt> will return +<tt>({7,4,1})</tt>. The order of the elements in the returned array will +always be taken from the left array. Elements in multisets are treated +the same as elements in arrays. When doing a set operator on a mapping +however, only the indices are considered. The values are just copied with +the indexes. If a particular index is present in both the right and left +argument to a set operator, the one from the right side will be used. +Example: <tt>([1:2]) | ([1:3])</tt> will return <tt>([1:3])</tt>. +<p> + +<h2>Indexing</h2> +The index and range operators are used to retreive information from a +complex data type. + +<center> +<p> +<table border=1> +<tr><th>Function</th> <th>Syntax</th> <th>Identifier</th> <th>Returns</th></tr> +<tr><td>Index</td> <td>a [ b ]</td><td>`[]</td> <td>Returns the index b from a.</td></tr> +<tr><td>Lookup</td> <td>a -><i>identifier</i></td> <td>`-></td> <td>Looks up the identifer. Same as a["<i>identifeir</i>"].</td></tr> +<tr><td>Assign index</td> <td>a [ b ] = c</td><td>`[]=;</td><td>Sets the index b in a to c.</td></tr> +<tr><td>Assign index</td> <td>a -><i>identifier</i> = c</td><td>`->=</td><td>Sets the index "<i>identifier</i>" in a to c.</td></tr> +<tr><td>Range</td> <td>a [ b .. c]</td> <td>`[..]</td> <td>Returns a slice of a starting at the index a and ending at b.</td></tr> +</table> +<p> +</center> + +The index operator can be written in two different ways. It can be +written as <tt><i>ob</i> [ <i>index</i> ]</tt> or +<tt><i>ob</i>-><i>identifier</i></tt>. However, the latter syntax is +equal to <tt><i>ob</i> [ "<i>identifier</i>" ]</tt>. You can only +index strings, arrays, mapping, multisets and objects, and some of these +can only be indexed on certain things as shown in this list: +<p> +<center> +<table border=1> +<tr> +<th>Operation</th> <th>Returns</th> +</tr> + +<tr> +<td><tt><i>string</i>[<i>int</i>]</tt></tt></td><td>Returns the ascii value of the Nth character in the string.</td> +</tr> + +<tr> +<td><tt><i>array</i>[<i>int</i>]</tt></td><td>Return the element in the array corresponding to the integer.</td> +</tr> + + +<tr> +<td><tt><i>array</i>[<i>int</i>]=<i>mixed</i></tt></td><td>Sets the element in the array to the mixed value.</td> +</tr> + +<tr> +<td><tt> + <i>multiset</i>[<i>mixed</i>]<br> + <i>multiset</i>-><i>identifier</i> + </tt></td><td>Returns 1 if the index is present in the multiset, 0 otherwise.</td> +</tr> + + +<tr> +<td><tt> + <i>multiset</i>[<i>mixed</i>]=<i>mixed</i><br> + <i>multiset</i>-><i>identifier=<i>mixed</i></i> + </tt></td><td>If the mixed value is <b>true</b> the index is added to the multiset. Otherwise the index is removed from the multiset.</td> +</tr> + + +<tr> +<td><tt> + <i>mapping</i>[<i>mixed</i>]<br> + <i>mapping</i>-><i>identifier</i> + </tt></td><td>Returns the value ascociated with the index, 0 if it is not found.</td> +</tr> + + +<tr> +<td><tt> + <i>mapping</i>[<i>mixed</i>]=<i>mixed</i><br> + <i>mapping</i>-><i>identifier</i>=<i>mixed</i></i> + </tt></td><td>Associate the second mixed value with the first mixed value.</td> +</tr> + +<tr> +<td><tt> + <i>object</i>[<i>string</i>]<br> + <i>object</i>-><i>identifier</i><br> + </tt></td><td>Returns the value of the named identifier in the object.</td> +</tr> + + +<tr> +<td><tt> + <i>object</i>[<i>string</i>]=<i>mixed</i><br> + <i>object</i>-><i>identifier</i>=<i>mixed</i><br> + </tt></td><td>Set the given identifer in the object to the mixed value. Only works if the identifier references a variable on the object.</td> +</tr> + +<tr> +<td><tt><i>string</i>[<i>int</i>..<i>int</i>]</tt></td><td>Return a piece of the string.</td> +</tr> + +<tr> +<td><tt><i>array</i>[<i>int</i>..<i>int</i>]</tt></td><td>Return a slice of the array.</td> +</tr> + +</table> +</center> + + +<!-- FIXME: tell more about indexing and ranges --> + +<h2>The assignment operators</h2> +There is really only one assignment operator, but it can be combined with +lots of other operators to make the code shorter. An assignment looks +like this: +<pre> + <i>variable</i> = <i>expression</i> ; +</pre> +The <i>variable</i> can be a local variable, a global variable or an index +in an array, object, multiset or mapping. This will of course set the +value stored in <i>variable</i> to <i>expression</i>. Note that the above +is also an expression which returns the value of the <i>expression</i>. +This can be used in some interesting ways: +<pre> + <i>variable1</i> = <i>variable2</i> = 1; // Assign 1 to both variables + <i>variable1</i> =(<i>variable2</i> = 1); // Same as above + + // Write the value of the expression, if any + if(<i>variable</i> = <i>expression</i>) + write(variable); +</pre> +Using assignments like this can however be confusing to novice users, or users +who come from a Pascal or Basic background. Especially the if statement +can be mistaken for <tt>if(<i>variable</i> == <i>expression</i>)</tt> which +would mean something completely different. As I mentioned earlier, the +assignment operator can be combined with another operator to form operators +that modify the contents of a variable instead of just assigning it. +Here is a list of all the combinations: +<p> +<center> +<table border=1> +<tr><th>Syntax</th> <th>Same as</th> <th>Function</th></tr> +<tr><td><tt><i>variable</i> += <i>expression</i><tt></td><td> <i>variable</i> = <i>variable</i> + <i>expression</i></td><td>Add <i>expression</i> to <i>variable</i></td></tr> +<tr><td><tt><i>variable</i> -= <i>expression</i><tt></td><td> <i>variable</i> = <i>variable</i> - <i>expression</i></td><td>Subtract <i>expression</i> from <i>variable</i></td></tr> +<tr><td><tt><i>variable</i> *= <i>expression</i><tt></td><td> <i>variable</i> = <i>variable</i> * <i>expression</i></td><td>Multiply <i>variable</i> with <i>expression</i></td></tr> +<tr><td><tt><i>variable</i> /= <i>expression</i><tt></td><td> <i>variable</i> = <i>variable</i> / <i>expression</i></td><td>Divide <i>variable</i> by <i>expression</i></td></tr> +<tr><td><tt><i>variable</i> %= <i>expression</i><tt></td><td> <i>variable</i> = <i>variable</i> % <i>expression</i></td><td>Modulo <i>variable</i> by <i>expression</i></td></tr> +<tr><td><tt><i>variable</i> <<= <i>expression</i><tt></td><td> <i>variable</i> = <i>variable</i> << <i>expression</i></td><td>Shift <i>variable</i> <i>expression</i> bits left</td></tr> +<tr><td><tt><i>variable</i> >>= <i>expression</i><tt></td><td> <i>variable</i> = <i>variable</i> >> <i>expression</i></td><td>Shift <i>variable</i> <i>expression</i> bits right</td></tr> +<tr><td><tt><i>variable</i> |= <i>expression</i><tt></td><td> <i>variable</i> = <i>variable</i> | <i>expression</i></td><td>Or <i>variable</i> with <i>expression</i></td></tr> +<tr><td><tt><i>variable</i> &= <i>expression</i><tt></td><td> <i>variable</i> = <i>variable</i> & <i>expression</i></td><td>And <i>variable</i> with <i>expression</i></td></tr> +<tr><td><tt><i>variable</i> ^= <i>expression</i><tt></td><td> <i>variable</i> = <i>variable</i> ^ <i>expression</i></td><td>Xor <i>variable</i> with <i>expression</i></td></tr> +</table> +</center> +<p> +In all of the above expression <i>variable</i> can also be an index in an +array, mapping or multiset. +<p> +<h2>The rest of the operators</h2> + +Now there are only a couple of operators left. I have grouped them together +in this section, not because they are not important, but because they do +not fit in any particular categories. + +<center> +<p> +<table border=1> +<tr><th>Function</th> <th>Syntax</th> <th>Identifier</th> <th>Returns</th></tr> +<tr><td>Calling</td> <td>a ( arguments ) </td><td>`()</td> <td>Calls the function a.</td></tr> +<tr><td>splice</td> <td>@ <i>a</i></td><td>none</td> <td>Sends each element in the array a as an individual argument to a function call.</td></tr> +<tr><td>Increment</td> <td>++ a</td> <td>none</td> <td>Increments a and returns the new value for a.</td></tr> +<tr><td>Decrement</td> <td>-- a</td> <td>none</td> <td>Decrements a and returns the new value for a.</td></tr> +<tr><td>Post increment</td><td>a ++</td> <td>none</td> <td>Increments a and returns the old value for a.</td></tr> +<tr><td>Post decrement</td><td>a --</td> <td>none</td> <td>Decrements a and return the old value for a.</td></tr> +<tr><td>casting</td> <td>(<i>type</i>) a</td><td>none</td> <td>Tries to convert a into a value of the specified type.</td></tr> +<tr><td>Null</td> <td>a, b</td> <td>none</td> <td>Evaluates a and b, then returns b.</td></tr> +</table> +<p> +</center> + +The most important of these operators is the calling operator. It is used +to call functions. The operator itself is just a set of parethesis placed +after the expression that returns the function. Any arguments to the function +should be placed between the parenthesis, separated by commas. We have +already seen many examples of this operator, although you might not have +realized it was an operator at the time. The function call operator can +do more than just calling functions though; if the 'function' is in fact +an array, the operator will loop over the array and call each element in +the array and return an array with the results. In fact, +<tt>({ foo, bar, gaznonk }) (1, 2, 3)</tt> is the same as +<tt>map(({ foo, bar, gaznonk }), call_function, 1, 2, 3)</tt>. +If on the other hand, the 'function' is a program, the operator will +clone an object from the program and call create() in the new object +with the arguments given. In fact, the function <tt>clone</tt> is +implemented like this: +<p> +<pre> + object clone(mixed p, mixed ... args) { ( (program)p )(@args); } +</pre> +<p> +On the subject of function calls, the splice operator should also be mentioned. +The splice operator is an at sign in front of an expression. The expression +should always be an array. The splice operator sends each of the elements +in the array as a separate argument to the function call. The splice operator +can only be used in an argument list for a function call. +<p> +Then there is the increment and decrement operators. The increment and +decrement operators are somwhat limited: they can only be used on +integers. They provide a short and fast way to add or subtract one +to an integer. If the operator is written before the lvalue +((tt>++<i>a</i></tt>) the returned value will be what the variable +is after the operator has added/subtracted one to it. If the operator +is after the lvalue (<tt><i>a</i>++</tt>) it will instead return the +value of the variable before it was incremented/decremented. +<p> +Casting is used to convert one type to another, not all casts are +possible. Here is a list of all casts that actually _do_ anything: +<p> +<center> +<table border=1> +<tr><th>casting from</th><th>to</th><th>operation</th></tr> +<tr><td>int</td><td>string</td><td>Convert the int to ASCII representation</tdt></tr> +<tr><td>float</td><td>string</td><td>Convert the float to ASCII representation</td></tr> +<tr><td>string</td><td>int</td><td>Convert decimal, octal or hexadecimal number to an int.</td></tr> +<tr><td>string</td><td>float</td><td>Convert ASCII number to a float.</td></tr> +<tr><td>string</td><td>program</td><td>String is a filename, compile the file and return the program. Results are cached.</td></tr> +<tr><td>string</td><td>object</td><td>This first casts the strning to a program, (See above) and then clones the result. Results are cached.</td></tr> +</table> +</center> +<p> +You can also use the cast operator to tell the compiler things. +If <tt>a</tt> is a variable of type mixed containing an int, then the +expression <tt>(int)a</tt> can be used intead of <tt>a</tt> and that will +tell the compiler that the type of that expression is <tt>int</tt>. +<p> +Last, and in some respect least, is the comma operator. It doesn't do +much. In fact, it simply evaluates the two arguments and then returns +the right hand one. This operator is mostly useful to produce smaller code, +or to make defines that can be used in expressions. +<p> +</center> +<p> +<h2>Operator precedence</h2> +When evaluating an expression, you can always use parenthesis to tell +the compiler in which order to evaluate things. Normally, the compiler +will evaluate things from left to right, but it will evaluate operators +with higher priority on the below before evaluating operators of lower +priority. +<p> +<center> +<table border=1 halign=center> +<tr><th>Operators</th></tr> +<tr><td><center><tt>(a) a() a[b] a->b a[b..c] ({}) ([]) (<>)</tt></center></td></tr> +<tr><td><center><tt>a++ a--</tt></center></td></tr> +<tr><td><center><tt>!a ~a (type)a ++a --a</tt></center></td></tr> +<tr><td><center><tt>a*b a/b a%b</tt></center></td></tr> +<tr><td><center><tt>a+b a-b</tt></center></td></tr> +<tr><td><center><tt>a>>b a<<b</tt></center></td></tr> +<tr><td><center><tt>a>b a>=b a<b a<=b</tt></center></td></tr> +<tr><td><center><tt>a==b a!=b</tt></center></td></tr> +<tr><td><center><tt>a&b</tt></center></td></tr> +<tr><td><center><tt>a^b</tt></center></td></tr> +<tr><td><center><tt>a|b</tt></center></td></tr> +<tr><td><center><tt>&&</tt></center></td></tr> +<tr><td><center><tt>||</tt></center></td></tr> +<tr><td><center><tt>=</tt></center></td></tr> +<tr><td><center><tt>a?b:c</tt></center></td></tr> +<tr><td><center><tt>@a</tt></center></td></tr> +<tr><td><center><tt>,</tt></center></td></tr> +</table> +</center> +<p> + +Examples: +<center> +<table border=1> +<tr><th>The expression</th><th>is evaluated in this order:</th></tr> +<tr><td><tt> 1+2*2 </tt></td><td><tt> 1+(2*2) </tt></td></tr> +<tr><td><tt> 1+2*2*4 </tt></td><td><tt> 1+((2*2)*4) </tt></td></tr> +<tr><td><tt> (1+2)*2*4 </tt></td><td><tt> ((1+2)*2)*4 </tt></td></tr> +<tr><td><tt> 1+4,c=2|3+5 </tt></td><td><tt> (1+4),(c=(2|3)+5) </tt></td></tr> +<tr><td><tt> 1+5 & 4 == 3 </tt></td><td><tt> (1+(5 & 4)) == 3 </tt></td></tr> +<tr><td><tt> c=1,99 </tt></td><td><tt> (c=1),99 </tt></td></tr> +<tr><td><tt> !a++ + ~--a()</tt></td><td><tt> (!(a++)) + (~((--a)())) </tt></td></tr> +</table> +</center> +<p> + +<HR NEWPAGE> + +<H1>Object orientation</h1> +As mention several times, Pike is object oriented. This does not mean that +it is identical to C++ in any way. Pike uses a less strict approach to +object orientation which creates a more relaxed programming style. For you +who have never come in contact with object oriented programming before, be +warned that the ideas expressed in Pike and in this chapter are my own and +does not nessecarily reflect what other people think about object +orientated programming. + +<h2>The approach</h2> +Think of the data type program as an executable file. Then we clone this +program and create an object. The object is then a running program. The +object has it's own data and it's own functions, however, it can work +together with other programs by calling functions in those objects. +The functions can be thought of as message carriers, tcp sockets or +just a way for programs to communicate. Now we have a running system with +many running programs, each preforming only the task it was designed for. +<p> +This analogy has one major flaw, when running programs in UNIX they actually +run simultaneously. UNIX is <i>multitasking</i>, Pike is not. When one +object is executing code, all the other objects has to wait until they +are called. An exception is if you are using <b>threads</b> as will be +descussed in a later chapter. + +<h2>How does this help?</h2> +Ok, why is it a good idea to use object oriented programming you ask? Well, +if you beleive what you hear, the biggest advantage is that you can re-use +your code in several projects. In my experience this is not the case. +<p> +In my experience, the advantages of object oriented programming are: +<dl> +<dt>Modular programming made easy +<dd>Using <b>The approach</b> makes it easy to divide a project into smaller + pieces, these pieces are usually easier to write than the whole. + +<dt>Local data scope +<dd>This is a very nifty with object oriented programs. If your program + uses several files, windows, stacks, tcp connections or whatever, you + simply write a <tt>program</tt> that handles one such file, window, + stack or tcp connection. If correctly written, you can then just create + many clones of that program. + +<dt>Using the same interface to different objects +<dd>I can write a function that takes a stream as an argument and writes + data to this stream. Later I might wish to write this data to a window + instead. I can then create an object that has the same methods as a stream + (specifically the <tt>write</tt> method) and send that to the function + that outputs the data. +</dl> + +Most of these things can be done without object orientation, but it is +object orientation that makes them easy. + +<h2>Pike and Object Orientation</h2> +In most object oriented langauges there is a way to write functions outside +of all classes. Some readers might think this is what we have been doing +until now. However, in Pike, all functions have to reside within a program. +When you write a simple script in Pike, the file is first compiled into a +<b>program</b> then cloned and then main() is called in that clone. All +this is done by the <b>master object</b>, which is compiled and cloned before +before all other objects. What the <b>master object</b> actually does is: +<pre> + program scriptclass=compile_file(argv[0]); // Load script + object script=scriptclass(); // clone script + int ret=script->main(sizeof(argv), argv); // call main() +</pre> + +Similarly, if you want to load another file and call functions in it, you +can do it with compile_file(), or you can use the cast operator and cast +the filename to a string. You can also use the module system, which we +will discuss further in the next chapter. +<p> +If you don't want to put each program in a separate file, you can use the +<tt>class</tt> keyword to write all your classes in one file. We have +already seen an example how this in chapter 4, but let's go over it in +more detail. The syntax looks like this: +<pre> + class <i>class_name</i> { + <i>class definition</i> + } +</pre> +This construction can be used almost anywhere within a normal program. +It can be used outside all functions, but it can also be used as an expression +in which case the defined class will be returned. In this case you may also +leave out the <i>class_name</i> and leave the class unnamed. The +<i>class definition</i> is simply the functions and programs you want to add +to the class. It is important to know that although the class is defined in +the same file as other classes and functions it can not immediately access +data in it's surroundings. Only constants defined before the class in the +same file can be used. Example: +<pre> + constant x = 17; + class foobar { + int test() { return x; } + }; +</pre> +This works because <tt>x</tt> is a <b>constant</b> if x had been a variable +or function it would not have worked. In future versions of Pike it may be +possible to do this with variables as well. To make it easier to progam, +defining a class is also to define a +constant with that name. Essentially, these two lines of code do the same +thing: +<pre> + class foo {}; + constant foo = class {}; +</pre> +Because classes defined as constants, it is possible to use a class defined +inside classes you define later, like this: +<pre> + class foo + { + int test() { return 17; } + }; + + class bar + { + program test2() { return foo; } + }; +</pre> + +<!-- FIXME: tell more --> + +<h2>Inherit</h2> +A big part of writing object oriented code is the ability to add functionality +to a program without changing (or even understanding) the original code. +This is what <tt>inherit</tt> is all about. +Let's say I want to change the hello_world program to write a version number +before it writes hello world, using <tt>inherit</tt> I could do this like +this: +<pre> + inherit "hello_world"; + int main(int argc, string *argv) + { + write("Hello world version 1.0\n"); + return ::main(argc,argv); + } +</pre> +What inherit does is that it copies all the variables and functions from the +inherited program into the current one. You can then re-define any function +or variable you want, and you can call the original one by using a <tt>::</tt> +in front of the function name. The argument to inherit can be one of the following: +<dl> +<dt> A string +<dd> This will have the same effect as casting the string to an program and then + doing inherit on this program. +<dt> A constant containing a program. +<dd> Any constant from this program, module or inherited program that contains a + program can be inherited. +<dt> A class name +<dd> A class defined with the <tt>class</tt> keyword is in fact added as a contant, + so the same rule as above applies. +</dl> +<p> + +Let's look at an example. We'll split up an eariler example into three parts +and let each inherit the previous part. It would look something like this: +<img src=inherit.gif> +Note that the actual code is not copied, only the list of references. +Also note that the list of inherits is copied when you inherit a program +this does not mean you can access those copied inherit with the <tt>::</tt> +operator, it is merely an implemention detail. Although this example does +not show an example of a re-defined function, it should be easy to see how +that works by just changing what an identifier is pointing at. + +<p> +<h2>Multiple inherit</h2> +You can inherit any amount of programs in one program, you can even inherit the +same thing more than once. If you do this you will a separate set of functions +and variables for each inherit. To access a specific function you need to name +your inherits. Here is an example of named inherits: +<pre> + inherit Stdio.File; // This inherit is named File + inherit Stdio.FILE; // This inherit is named FILE + inherit "hello_word"; // This inherit is named hello_world + inherit Stdio.File : test1; // This inherit is named test1 + inherit "hello_world: : test2; // This inherit is named test2 + + void test() + { + File::read(); // Read data from the first inherit + FILE::read(); // Read data from the second inherit + hello_world::main(0,({})); // Call main in third inherit + test1::read(); // Read data from fourth inherit + test2::main(0,({})); // Call main in fourth inherit + ::read(); // Read data from all inherits + } +</pre> + +As you can see it would be impossible to separate the different read and +main functions without using inherit names. If you would try to calling +just <tt>read</tt> without any <tt>::</tt> or inherit name in front of it +Pike will call the last read defined, in this case it will call read in +the fourth inherit. +<p> +If you leave the inherit name blank and just call <tt>::read</tt> Pike will +call all inherited read() functions. If there is more than one inherited +read function the results will be returned in an array. +<p> +Let's look at another example: +<pre> + #!/usr/local/bin/pike + + inherit Stdio.File : input; + inherit Stdio.File : output; + + int main(int argc, string *argv) + { + output::create("stdout"); + for(int e=0;e<sizeof(argv);e++) + { + input::open(argv[e],"r") + while(s=input::read(4096)) output::write(s); + } + } +</pre> +This short piece of code works a lot like the UNIX command <tt>cat</tt>. +It reads all the files given on the command line and writes them to +stdout. As an example, I have inherited Stdio.File twice to show you +that both files are usable from my program. + +<h2>Pike Inherit compared to other languages</h2> +Many other languages assign special meaning to inherit. Most common is the +notion that if you inherit a class, it means that your class should obey +the same rules as the inherited class. In Pike, this is not nessesarily so. +You may wish you use inherit in Pike like this, but you can just as well +choose not to. This may confuse some programmers with previous experience +in object oriented programming. + +<h2>Modifiers</h2> +Sometimes, you may wish to hide things from inheriting programs, or +prevent functions from being called from other objects. To do so you use +<b>modifiers</b>. A modifier is simply a word written before a variable +definition, function definition, class definition or an inherit that +specifies how this identifer should interact with other objects and programs. +These modifiers are available: +<dl> +<dt><tt>static</tt> +<dd>Static hides this identifer from the index and arrow operators, which + makes it impossible for other objects to call this function unless a + function pointer to it is returned from inside this program. +<dt><tt>nomask</tt> +<dd>This prevents other objects from re-defining this identifier in + program that inherit this program. +<dt><tt>private</tt> +<dd>This prevents inheriting programs from accessing this identifier. + Note that inheriting program can still re-define the identifer. + Also note that <tt>private</tt> does not imply <tt>static</tt>. +<dt><tt>public</tt> +<dd>This is the oppsite of <tt>private</tt>. This is the default for + all identifiers. <tt>public</tt> can be used to override the effects + of a private inherit. +<dt><tt>protected</tt> +<dd>Reserved for future use. +</dl> +When modifiers are used in conjunction with inherit, all the variablers, +functions and classes copied from the inherited class will be modified +with the keywords used. For instance, <tt>private inherit</tt> means that +the identifers from this inherit will not be available to program inheriting +this program. <tt>static private inherit</tt> will also hide those identifers +from the index and arrow operators, making the inherit available only to the +code in this program. + +<h2>Operator Overloading</h2> +Sometimes you want an object to act as if it was a string, an integer or some +other data type. It is especially interesting to be able to use the normal +operators on objects to allow short and readable syntax. In Pike, special +methods are called when an operator is used with an object. To some extent, +this is work in progress, but what has been done so far is very useful and +will not be subject to change. +<p> +The following table assumes that a and b are objects and shows what will be +evaluated if you use that particular operation on an object. Note that some +of these operators, notably <tt>==</tt> and <tt>!</tt> have default behaviour +which will be used if the corresponding method is not defined in the object. +Other operators will simply fail if called with objects. Refer to the Chapter +XXXX <!--FIXME--> for information on which operators can operate on objects +without operator overloading. +<center> +<table border=1> +<tr><th>Operation</th><th>Will call</th></tr> +<tr><td>a+b</td><td>a->`+(b)</td></tr> +<tr><td>a+b+c+d</td><td>a->`+(b,c,d)</td></tr> +<tr><td>a-b</td><td>a->`-(b)</td></tr> +<tr><td>a&b</td><td>a->`&(b)</td></tr> +<tr><td>a|b</td><td>a->`|(b)</td></tr> +<tr><td>a^b</td><td>a->`^(b)</td></tr> +<tr><td>a>>b</td><td>a-`>>(b)</td></tr> +<tr><td>a<<b</td><td>a-`<<(b)</td></tr> +<tr><td>a*b</td><td>a->`*(b)</td></tr> +<tr><td>a*b*c*d</td><td>a->`*(b,c,d)</td></tr> +<tr><td>a/b</td><td>a->`/(b)</td></tr> +<tr><td>a%b</td><td>a->`%(b)</td></tr> +<tr><td>~a</td><td>a->`~()</td></tr> +<tr><td>a==b</td><td>a->`==(b) or b->`==(a)</td></tr> +<tr><td>a!=b</td><td>!( a->`==(b) ) or !( b->`==(a) )</td></tr> +<tr><td>a<b</td><td>a->`<(b)</td></tr> +<tr><td>a>b</td><td>a->`>(b)</td></tr> +<tr><td>a<=b</td><td>!( b->`>(a) )</td></tr> +<tr><td>a>=b</td><td>!( b->`<(a) )</td></tr> +<tr><td>(int)a</td><td>a->cast("int")</td></tr> +<tr><td>!a</td><td>a->`!()</td></tr> +<tr><td>if(a) { ... } </td><td>!( a->`!() )</td></tr> +<tr><td>a[b]</td><td>a->`[](b)</td></tr> +<tr><td>a[b]=c</td><td>a->`[]=(b,c)</td></tr> +<tr><td>a->foo</td><td>a->`->("foo")</td></tr> +<tr><td>a->foo=b</td><td>a->`->=("foo",b)</td></tr> +<tr><td>sizeof(a)</td><td>a->_sizeof()</td></tr> +<tr><td>indies(a)</td><td>a->_indices()</td></tr> +<tr><td>values(a)</td><td>a->_values()</td></tr> +<tr><td>a(b)</td><td>a->`()(b)</td></tr> +</table> + +Here is a really silly example of a program that will write 10 +to stdout when executed. + +<pre> + #!/usr/local/bin/pike + class three { + int `+(int foo) { return 3+foo; } + }; + + int main() + { + write(sprintf("%d\n",three()+7)); + } +</pre> + +It is important to know that some optimizations are still performed even +when operator overloading is in effect. If you define a multiplication operator +and multiply your object with one, you should not be surprised if the +multiplication operator is never called. This might not always be what you +expect, in which case you are better off not using operator overloading. + +</center> +<p> +<table cellpadding=10 width="100%" border=1 cellspacing=0> +<tr><td> +<H2>Simple exercises</H2> +<ul> +<li> Make a program that clones 10 hello world and then runs main() in + each one of them. +<li> Modify the register program to use an object for each record. +<li> Modify the register program to use the following search funtion: +<pre> + void find_song(string title) + { + string name, song; + int hits; + + title=lower_case(title); + + foreach(indices(records),name) + { + if(string song=records[name][title]) + { + write(name+"; "+song+"\n"); + hits++; + } + } + + if(!hits) write("Not found.\n"); + } +</pre> + +</ul> +</td></tr> +</table> +<!-- FIXME add more examples above --> + + +<HR NEWPAGE> + + +<h1>Modules</h1> +A module is a software package that plugs into the Pike programming +environment. They provide you with simple interfaces to system routines +and they also constitute a neat way to use your own C/C++ code from +within Pike. Pike comes with a number of modules that are ready to use. +In this chapter I will explain the basics of modules and how to use them. + +<dl> +<dt>Stdio +<dd>This module contains file I/O routines. +<dt>Array +<dd>This function contains functions that operate on arrays. +<dt>Gdbm * +<dd>This module contains support for Gdbm databases. +<dt>Getopt +<dd>Routines to parse command line options +<dt>Gmp * +<dd>Support for large numbers. +<dt>Gz * +<dd>Deflate packing algorithms. +<dt>Image +<dd>Image manipulating routines. +<dt>Mysql * +<dd>Simple sql database support. +<dt>Regexp +<dd>Regexp matching routines. +<dt>Simulate +<dd>Routines to emulate old pike routines. +<dt>String +<dd>Routines that operate on strings. +<dt>Thread * +<dd>Thread support functions. +<dt>Yp * +<dd>Network Information System support. +</dl> +<p> +* These modules might not be available depending on how Pike was compiled + and weather support for these functions exists on your system. +<p> + +<h2>How to use modules</h2> +A module is a bunch of functions, programs or other modules collected in +one symbol. For instance, the module <tt>Stdio</tt> contains the objects +<tt>stdin</tt>, <tt>stdout</tt> and <tt>stderr</tt>. To access these objects +you can write <tt>Stdio.stdin</tt>, <tt>Stdio.stdout</tt> or +<tt>Stdio.stderr</tt> anywhere in your program where an object of that type +is acceptable. If you use <tt>Stdio</tt> a lot you can use put +<tt>import Stdio;</tt> in the beginning of your program. This will import +all the identifiers from the module Stdio into your program, making it +possible to write just <tt>stdin</tt> instead of <tt>Stdio.stdin</tt>. + +<h2>Where do modules come from?</h2> +Modules are not loaded until you use them, which saves memory unless you use +all the modules. However, if you want to write your own modules it is important +to know how modules are located and loaded. +<p> +When you use <tt>Stdio</tt> Pike will look for the that module: +<ol> +<li> In the same directory as the source. +<li> In directories added with add_module_path() +<li> In directories specified with -M on the command line. +<li> In directories in the environment variable PIKE_MODULE_PATH +<li> In the directory with builtin modules, usually /usr/local/pike/lib/modules/ +</ul> + +For each of these directories, Pike will do the following: +<ol> +<li> If there is a file called Stdio.pmod.pike, Pike will load this + Pike program, clone it and use that as a module. +<li> If there is a file called Stdio.pmod.so, Pike will load this + with load_module(), clone it and use that as a module. +<li> If there is a directory called Stdio.pmod, Pike will create a module + containing all the modules in that dir as identifiers. If there is + a module called <tt>module</tt> in that directory, all identifiers + from that module will overload any modules actually present in the + directory. +</ol> + +As you can see, quite a lot of work goes into finding the modules, this +makes it possible to choose the most convenient way build your own Pike +modules. +<p> + +<h2> The <tt>.</tt> operator. </h2> +The period operator is not really an operator, as it is always evaluated +during the compilation. It works similar to the index and arrow operators, +but can only be used on constant values such as modules. In most cases, +modules are simply a clone of a program, in which case the identifiers in +the module will be the same as those in the program. But some modules, +like those created from directories, overload the index operator so that +the identifiers in the module can be something else than those in the program. +For directory modules, the index operator looks in the directory it was +cloned for to find the identifiers. + +<h2> How to write a module </h2> +Here is an example of a simple module: +<pre> + constant PI = 3.15; + float cos2(float f) { return pow(cos(f),2.0); } +</pre> +if we save this short file as <tt>Trig.pike.pmod</tt> we can now use this +module like this: +<pre> + int main() + { + write(spritnf("%f\n",Trig.cos2(Trig.PI)); + } +</pre> +or like this: +<pre> + import Trig; + + int main() + { + write(spritnf("%f\n",cos2(PI)); + } +</pre> + +<table cellpadding=10 width="100%" border=1 cellspacing=0> +<tr><td> +<H2>Simple exercises</H2> +<ul> +<li> Save the hello_world.pike program as hello_world.pike.pmod, then make + a program that loads this module and calls it's main(). +<li> Make a directory called <tt>Programs.pmod</tt> and put all the examples you + have written so far in it. Make a program that runs one of those + programs. Make sure the program can be modified to run another of + your examples by changing what module it loads. +<li> Copy hello_world.pike.pmod to programs/module.pike.pmod, now write + a program that runs hello_world without actually using the identifier + <tt>hello_world</tt>. +<li> Try putting <tt>Programs.pmod</tt> in another directory, now try to + run the programs from the last two examples. +</ul> +</td></tr> +</table> + +<HR NEWPAGE> + + +<h1>6. File I/O</h1> +Programming without reading and writing data from files, sockets, keybaord +etc. would be quite pointless. Luckily enough, Pike provides you with an +object oriented interface to files, pipes and TCP sockets. All I/O functions +and classes are collected in the module <tt>Stdio</tt>. + +<a name=Stdio.File> +<h2>Stdio.File</h2> +This is the basic I/O object, it provides socket communicatoin as well +as file access. It does not buffer reads and writes or provide line-by-line +reading, that is done in the FILE object. <tt>Stdio.File</tt> is completely +written in C. What follows is a description of all the functions in +<tt>Stdio.File</tt>. + +<hr noshade size=1> +<a name=Stdio.File.create> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->create</tt> - init file struct +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object Stdio.File();<br> +or<br> +object Stdio.File(string <I>fd</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +When cloning a file, you can specify that you want to clone +stdin, stdout or stderr, by giving "stdin", "stdout" or "stderr" to +clone as a second argument. If no second argument is given, +an unitialized file will be cloned. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#clone>clone</a> +<p> +</dl> +</a> + +<hr noshade size=1> +<a name=Stdio.File.open> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->open</tt> - open a file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int open(string <I>filename</I>, string <I>how</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Open a file for read, write or append. The variable how should +contain one or more of the following letters: +<p><table border=0 cellpadding=0 cellspacing=0> +<tr valign=top><td> 'r' </td><td> open file for reading </td></tr> +<tr valign=top><td> 'w' </td><td> open file for writing </td></tr> +<tr valign=top><td> 'a' </td><td> open file for append (use with 'w') </td></tr> +<tr valign=top><td> 't' </td><td> truncate file at close (use with 'w') </td></tr> +<tr valign=top><td> 'c' </td><td> create file if it doesn't exist (use with 'w') </td></tr> +<tr valign=top><td> 'x' </td><td> fail if file already exist (use with 'c') </td></tr> +</table> + +<p>How should _always_ contain at least one of 'r' or 'w'. +<p>Returns 1 on success, 0 otherwise. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.close>Stdio.File->close</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.close> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->close</tt> - close file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int close(string <I>how</I>);<br> +or<br> +int close();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Close the file. Optionally, specify "r", "w" or "rw" to close just +the read, just the write or both read and write part of the file +respectively. Note that this funciton will not call the +close_callback. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.open>Stdio.File->close</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.read> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->read</tt> - read data from a file or stream +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string read(int <I>nbytes</I>);<br> +or<br> +string read(int <I>nbytes</I>, int <I>notall</I>);<br> +or<br> +string read();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Read tries to read nbytes bytes from the file, and return it as a +string. If something goes wrong, zero is returned. +<p>If a one is given as second argument to read(), read will not try +it's best to read as many bytes as you asked it to read, it will +merely try to read as many bytes as the system read function will +return. This mainly useful with stream devices which can return +exactly one row or packet at a time. +<p> +If no arguments are given, read will read to the end of the file/stream. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.write>Stdio.File->write</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.write> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->write</tt> - write data to a file or stream +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int write(string <I>data</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Write data to file or stream and return how many bytes that was +actually written. -1 is returned if something went wrong and no +bytes had been written. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.read>Stdio.File->read</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.seek> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->seek</tt> - seek to a position in a file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int seek(int <I>pos</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Seek to a position in a file, if pos is less than zero, seek to +position pos relative end of file. Return -1 for failiure, or +the old position in the file when successful. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.tell>Stdio.File->tell</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.tell> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->tell</tt> - tell where we are in a file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int tell();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the current position in the file. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.seek>Stdio.Fileile->seek</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.stat> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->stat</tt> - do file_stat on an open file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int *stat();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the same information as the efun file_stat, +but for the file it is called in. If file is not an open file, +zero will be returned. Zero is also returned if file is a pipe or +socket. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#file_stat>file_stat</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.errno> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->errno</tt> - what was last error? +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int errno();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the error code for the last command on this file. +Error code is normally cleared when a command is successful. +<p> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.set_buffer> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->set_buffer</tt> - set internal socket buffer +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void set_buffer(int <I>bufsize</I>, string <I>mode</I>);<br> +or<br> +void set_buffer(int <I>bufsize</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sets the internal buffer size of a socket or stream, +the second argument allows you to set the read or write buffer by +specifying "r" or "w". It is not guaranteed that this function +actually does anything, but it certainly helps to increase data +transfer speed when it does. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.open_socket>Stdio.File->open_socket</a> and <a href=#Stdio.Port.accept>Stdio.Port->accept</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.set_nonblocking> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->set_nonblocking</tt> - make stream nonblocking +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void set_nonblocking(function read_callback,<br> +<dl><dt><dd>function write_callback,<br> +function close_callback);<br> +</dl>or<br> +void set_nonblocking();<br> +<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sets a stream to nonblocking mode. When data arrives on +the stream, read_callback will be called with some or all of this data. +When the stream has buffer space over for writing, write_callback is +called so you can write more data to it. If the stream is closed at +the other end, close_callback is called. All callbacks will have the +id of file as first argument when called. +<p>If no arguments are given, the callbacks are not changed. The +stream is just set to nonblocking mode. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.set_blocking>Stdio.File->set_blocking</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.set_read_callback> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->set_read_callback</tt> - set the read callback +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void set_read_callback(function read_callback)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sets the read callback for the file. The read callback +is called whenever there is data to read from the file. Note that +this function does not set the file nonblocking. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.set_nonblocking>Stdio.File->set_nonblocking</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.set_write_callback> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->set_write_callback</tt> - set the write callback +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void set_write_callback(function write_callback)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sets the write callback for the file. The write callback +is called whenever there is buffer space available to write to for +the file. Note that this function does not set the file nonblocking. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=Stdio.File.set_nonblocking>Stdio.File->set_nonblocking</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.set_close_callback> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->set_close_callback</tt> - set the close callback +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void set_close_callback(function close_callback)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sets the close callback for the file. The close callback +is called when the remote end of a socket or pipe is closed. Note that +this function does not set the file nonblocking. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.set_nonblocking>Stdio.File->set_nonblocking</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.set_blocking> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->set_blocking</tt> - make stream blocking +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void set_blocking();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sets a stream to blocking mode. ie. all reads and writes +will wait until data has been written before returning. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=Stdio.File.set_nonblocking>Stdio.File->set_nonblocking</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.set_id> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->set_id</tt> - set id of this file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void set_id(mixed <I>id</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sets the id of this file. The id is mainly used as an +identifier that is sent as the first arguments to all callbacks. The +default id is 0. Another possible use of the id is to hold all data +related to this file in a mapping or array. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.query_id>Stdio.File->query_id</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.query_id> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->query_id</tt> - get id of this file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed query_id();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the id of this file. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.set_id>Stdio.File->set_id</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.query_read_callback> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->query_read_callback</tt> - return the read callback function +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>function query_read_callback();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the read_callback, which is set with +set_nonblocking. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.set_nonblocking>Stdio.File->set_nonblocking</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.query_write_callback> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->query_write_callback</tt> - return the write callback function +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>function query_write_callback();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the write_callback, which is set with +set_nonblocking. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.set_nonblocking>Stdio.File->set_nonblocking</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.query_close_callback> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File.query_close_callback</tt> - return the close callback function +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>function query_close_callback();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the close_callback, which is set with +set_nonblocking. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.set_nonblocking>Stdio.File->set_nonblocking</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.dup> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->dup</tt> - duplicate a file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object(Stdio.File) dup();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns a clone of Stdio.File with all variables +copied from this file. Note that all variables, even id, is copied. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.assign>Stdio.File->assign</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.dup2> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->dup2</tt> - duplicate a file over another +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int dup2(object(Stdio.File) <I>to</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function works similar to Stdio.File->assign, but instead of making +the argument a reference to the same file, it creates a new file +with the same properties and places it in the argument. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>/* Redirect stdin to come from the file 'foo' */<br> +object o=Stdio.File();<br> +o->open("foo","r");<br> +o->dup2(Stdio.File("stdin"));<br> +</tt> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.assign>Stdio.File->assign</a> and <a href=#Stdio.File.dup>Stdio.File->dup</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.assign> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->assign</tt> - assign a file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void assign(object <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function takes a clone of /precompiled/file and assigns all +variables this file from it. It can be used together with file->dup +to move files around. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.dup>Stdio.File->dup</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.open_socket> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->open_socket</tt> - open a socket +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int open_socket();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This makes this file into a socket ready for connection. The reason +for this function is so that you can set the socket to nonblocking +or blocking (default is blocking) before you call Stdio.File->connect() +This function returns 1 for success, 0 otherwise. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.connect>Stdio.File->connect</a> and <a href=#Stdio.File.set_nonblocking>Stdio.Fileile->set_nonblocking</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.connect> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->connect</tt> - connect a socket to something. +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int connect(string <I>ip</I>,int <I>port</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This funcion connects a socket previously created with +Stdio.File->open_socket to a remote socket. The argument is the ip name +or number fot he remote machine. +<p>This function returns 1 for success, 0 otherwise. Note that if the +socket is in nonblocking mode, you have to wait for a write or close +callback before you know if the connection failed or not. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.query_address>Stio.File->query_address</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.query_address> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->query_address</tt> - get adresses +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string query_address();<br> +or<br> +string query_address(1);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the remote or local address of a socket on the +form "x.x.x.x port". Without argument, the remote address is returned, +with argument the local address is returned. If this file is not a +socket, not connected or some other error occurs, zero is returned. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File.connect>Stdio.File->connect</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.pipe> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->pipe</tt> - create a two-way pipe +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object pipe();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function creates a pipe between the object it was called in +and an object that is returned. The two ends of the pipe are +indistinguishable. If the object is this function is called in +was open to begin with, it is closed before the pipe is created. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#fork>fork</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.File.set_close_on_exec> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.File->set_close_on_exec</tt> - set / clear the close on exec flag +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void set_close_on_exec(int <I>onoff</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function determines weather this file will be closed when +calling exece. Default is that the file WILL be closed on exec +except for stdin, stdout and stderr. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#exece>exece</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<!-- FIXME insert examples of how to use Stdio.File here --> +<!-- FIXME Don't forget to put a TCP example here --> + +</a> + +<a name=Stdio.FILE> +<h2>Stdio.FILE</h2> +Stdio.FILE is a buffered version of Stdio.File, it inherits Stdio.File and +has most of the functionalty of Stdio.File. However, it has a an input buffer +that allows line-by-line input. Note that the output part of Stio.FILE is +not buffered at this moment. The added functionality of Stdio.FILE is +described here: + +<hr noshade size=1> +<a name=Stdio.FILE.gets> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.FILE->gets</tt> - get one line +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string gets();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns one line from the FILE, it returns zero if +no more lines are available. +<p> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.FILE.printf> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.FILE->printf</tt> - formatted print +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string printf(string <I>format</I>, mixed ... <I>data</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function does aproximately the same as: +write(sprintf(format,@data)) +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#sprintf>sprintf</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.FILE.ungets> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.FILE->ungets</tt> - put a string back in the buffer +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string ungets(string <I>s</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function puts a string back in the input buffer. The string +can then be read with read, gets or getchar. +<p> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.FILE.getchar> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.FILE->getchar</tt> - get one character from the input stream +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int getchar();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns one character from the input stream. Note +that the return value is the ascii value of the character, not +a string containing one character. +<p> +</dl> + +</a> + +<!-- FIXME, example of how to use Stdio.FILE here --> + +</a> + +<h2>Standard streams</h2> +Any UNIX program has three files open from the beginning. These are called +standard input, standard output and standard error stream. These streams +are available from Pike as well. They are called <tt>Stdio.stdin</tt>, +<tt>Stdio.stdout</tt> and <tt>Stdio.stderr</tt> respectively. Standard +input is a clone of <tt>Stdio.FILE</tt>, which means you can use the line +oriented functions. <tt>Stdio.stdout</tt> and <tt>Stdio.stderr</tt> are +simply clones of <tt>Stdio.File</tt>. +<p> +Example: +<pre> + int main() + { + int line; + while(string s=Stdio.stdin.gets()) + write(sprintf("%5d: %s\n",line++,s)); + } +</pre> +This example will read lines from standard input for as long as there +are more lines to read. Each line will then be written to stdout together +with the line number. We could use <tt>Stdio.stdout.write</tt> instead +of just <tt>write</tt> they are the same function. + +<h2>Other Stdio functions</h2> +The Stdio module also contains a collection of high level IO functions +to make it easy to write short and readable Pike programs. Most of these +functions are implemented using Stdio.File and Stdio.FILE. + +<a name=Stdio.file_size> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.file_size</tt> - return the size of a file in bytes +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int file_size(string <I>file</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Give the size of a file. Size -1 indicates that the file either +does not exist, or that it is not readable by you. Size -2 +indicates that it is a directory. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.write_file>Stdio.write_file</a> and <a href=#Stdio.read_bytes>Stdio.read_bytes</a> +<p> +</dl> +</a> + +<hr noshade size=1> +<a name=Stdio.perror> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.perror</tt> - print error +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void perror(string <I>s</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function prints a message to stderr along with a description +of what went wrong if available. It uses the system errno to find +out what went wrong, so it is only applicable to IO errors. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.werror.html>Stdio.werror</a> +<p> +</dl> + +</a> + +<hr noshade size=1> + +<a name=Stdio.read_bytes> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.read_bytes</tt> - read a number of bytes into a string from a file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string read_bytes(string <I>file</I>,int <I>start</I>,int <I>len</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Read len number of bytes from file file staring at byte start and +return it as a string. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.write_file>Stdio.write_file</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.read_file> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.read_file</tt> - read a number of lines into a string from file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string read_file(string <I>file</I>, int <I>start</I>, int <I>len</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Read 'len' lines from the file 'file' after skipping 'start' lines +and return those lines as a string. If start and len are omitted +the whole file is read. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.read_bytes>Stdio.read_bytes</a> and <a href=Stdio.write_file.html>Stdio.write_file</a> +<p> +</dl> + +</a> + +<hr noshade size=1> + +<a name=Stdio.readline> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.readline</tt> - read a line from stdin +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string readline(string <I>prompt</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function writes the string 'prompt' and then waits until the +user has entered a line from the keyboard. If the readline library +was available when Pike was compiled the user will have history and +line edithing at his/her disposal when entering the line. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File>Stdio.File</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.werror> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.werror</tt> - write to stderr +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void werror(string <I>s</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Writes a message to stderr. Stderr is normally the console, even if +the process output has been redirected to a file or pipe. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=#Stdio.File>Stdio.File</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.write_file> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.write_file</tt> - append a string to a file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int write_file(string file, string str)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Append the string str onto the file file. Returns number of bytes written. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.read_bytes.html>Stdio.read_bytes</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<!--FIXME insert doc for write_bytes here!!! ---> +<hr noshade size=1> + +<a name=Stdio.Port> +<tt>Listening to sockets</tt> +Stdio.File can handle connections to any TCP socket, but it can not listen +to a local TCP port. For this purpose there is a special class called +<tt>Stdio.Port</tt>. <tt>Stdio.Port</tt> cannot read or write any data, but +it can accept connections which will be returned as clones of Stdio.File. +These are the methods available in <tt>Stdio.Port</tt>: + +<hr noshade size=1> +<a name=Stdio.Port.bind> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.Port->bind</tt> - open socket and bind it to a port +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int bind(int <I>port</I>);<br> +or<br> +int bind(int <I>port</I>,function <I>accept_callback</I>);<br> +or<br> +int bind(int <I>port</I>,function <I>accept_callback</I>, string <I>ip</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Bind opens a sockets and binds it to port number on the local machine. +If the second argument is present, the socket is set to nonblocking +and the callback funcition is called whenever something connects to +the socket. The callback will receive the id for this port as argument. +Bind returns 1 on success, and zero on failiure. +<p>If the optional argument 'ip' is given, bind will try to bind to +this ip name (or number). +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.Port.accept>Stdio.Port->accept</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.Port.listen_fd> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.Port->listen_fd</tt> - listen to an already open port +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int listen_fd(int <I>fd</I>);<br> +or<br> +int listen_fd(int <I>fd</I>,function <I>accept_callback</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function does the same as Stdio.Port->bind, except that instead +of creating a new socket and bind it to a port, it expects that +the filedescriptor 'fd' is an already open port. +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +This function is only for the advanced user, and is generally used +when sockets are passed to Pike at exec time. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.Port.bind>Stdio.Port->bind</a> and <a href=#Stdio.Port.accept>Stdio.Port->accept</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.Port.create> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.Port-create</tt> - create and/or setup a port +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object(Stdio.Port) Stdio.Port("stdin")<br> +or<br> +object(Stdio.Port) Stdio.Port("stdin",function accept_callback)<br> +or<br> +object(Stdio.Port) Stdio.Port("stdin",function accept_callback)<br> +or<br> +object(Stdio.Port) Stdio.Port(int port)<br> +or<br> +object(Stdio.Port) Stdio.Port(int port,function accept_callback)<br> +or<br> +object(Stdio.Port) Stdio.Port(int port,function accept_callback, string ip)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +When create is called with 'stdin' as argument, a socket is created +out of the file descriptor 0. This is only useful if that actually +IS a socket to begin with. When create is called with an int as first +argument, it does the same as bind() would do with the same arguments. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#clone>clone</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.Port.set_id> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.Port->set_id</tt> - set the id of a port +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void set_id(mixed <I>id</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sets the id used for accept_callback by this port. +The default id is this_object(). +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.Port.query_id>Stdio.Port->query_id</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.Port.query_id> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.Port->query_id</tt> - Return the id for this port. +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed query_id();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the id for this port. The id is normally the +first argument to accept_callback. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.Port.set_id>Stdio.Port->set_id</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.Port.errno> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.Port->errno</tt> - return the last error +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int errno();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +If the last call done on this port failed, errno will return an +integer describing what went wrong. Refer to your unix manual for +further information. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.Port.errno>Stdio.Port->errno</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=Stdio.Port.accept> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>Stdio.Port->accept</tt> - accept a connection +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object accept();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function completes a connection made from a remote machine to +this port. It returns a two-way stream in the form of a copy of +Stdio.File. The new file is by default set to blocking. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#Stdio.File>Stdio.File</a> +<p> +</dl> + +</a> +<hr noshade size=1> + +<!-- FIXME, example of Stdio.Port here --> + +<HR NEWPAGE> + +<h1>Threads</h2> +Threads used to run several Pike functions at the same time without having to start +several Pike processes. It often simplifies coding to use threads and because the +threads are within the same process, data can be shared or sent to other threads +very fast. Threads are not supported on all systems, you may test if you have +thread support with the preprocessor constructoin <tt>#if efun(thread_create</tt>. +Pike needs POSIX or UNIX thread support when compiled to support threads. +<p> +<a href=thread_create> +<h2>Starting a thread</h2> +Starting a thread is very easy. You simply call <tt>thread_create</tt> with a function +pointer and any arguments it needs and that function will be executed in a +separate thread. The function <tt>thread_create</tt> will return immediately and both +the calling function and the called function will execute at the same time. Example: +<pre> + void foo(int x) + { + for(int e=0;e<5;e++) + { + sleep(1); + write("Hello from thread "+x+".\n"); + } + } + + int main() + { + thread_create(foo, 2); + thread_create(foo, 3); + foo(1); + } +</pre> +This may all seem very simple, but there are a few complications to +watch out for: +<dl> +<dt> Accessing unlocked data +<dd> Look at this code: +<pre> + void mapadd(mapping m, int i, int j) + { + if(map[i]) + map[i]+=({j}); + else + map[i]=({j}); + } +</pre> +This is quite harmless as long as it is only used from one thread at a time, +but if two threads call it it at the same time, there is a slight chance that +both threads will discover that <tt>map[i]</tt> is zero and both threads will +then do <tt>map[i]=({j});</tt> and one value of <tt>j</tt> will be lost. +These type of bugs can be extremely hard to debug. + +<dt> Deadlocks +<dd> Deadlocks arise when two threads are waiting for each other to do something. + This bug can often arise when several threads needs access to a number of + resources such as files or other I/O devices. What may happen is that one + thread has locked device #1 and is trying to lock device #2 while another + thread has locked device #2 and is trying to lock device #1. These types + of bugs are generally easier to find, but may require a lot of work to fix. +</dl> + +The above problems can all be solved with the help of Mutexes and Conditions. + + + +<ul> + <li> thread_create + <li> this_thread + <li> Mutex + <li> Condition + <li> Fifo + <li> Queue +</ul> +<HR NEWPAGE> + +<H1>9. Builtin Programs</h2> +(the rest of them) +<!-- FIXME, finish module interface before writing this chapter --> +<ul> + <li>Gdbm + <li>Mpz + <li>regexp + <li>string_buffer + <li>heap + <li>priority_queue + <li>Other available modules: image, curses +</ul> +<HR NEWPAGE> + +<H1>10. The preprocessor</h1> +<a name=preprocessor> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>preprocessor</tt> - textually process code before compiling +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Pike has a builtin C-style preprocessor. It works similar to old +C preprocessors but has a few extra features. This file describes +the different preprocessor directives. +<p> +<dt><b> <font size=+1>P</font><font size=-1>REPROCESSOR</font> <font size=+1>D</font><font size=-1>IRECTIVES</font></b><dd> +<tt><dl><dt><dd>#!<br> +#define<br> +#elif<br> +#else<br> +#elseif<br> +#endif<br> +#error<br> +#if<br> +#ifdef<br> +#ifndef<br> +#include<br> +#line<br> +#pragma<br> +#undef<br> +</dl></tt> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#pike>pike</a> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=error> +<dl> +<dt><b> <font size=+1>D</font><font size=-1>IRECTIVE</font></b><dd> +<tt>#!<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This directive is in effect a comment statement, since the +preprocessor will ignore everything to the end of the line. +This is used to write unix type scripts in Pike by starting +the script with +<p>#!/usr/local/bin/pike + +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=error> +<dl> +<dt><b> <font size=+1>D</font><font size=-1>IRECTIVE</font></b><dd> +<tt>#define<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +The simplest way to use define is to write +<p><dl><dt><dd>#define <identifier> <replacement string><br> +</dl> +<p>which will cause all subsequent occurances of 'identifier' to be +replaced with the replacement string. +<p>Define also has the capability to use arguments, thus a line like +<p><dl><dt><dd>#define <identifier>(arg1, arg2) <replacement string><br> +</dl> +<p>would cause identifer to be a macro. All occurances of +'identifier(something1,something2d)' would be replaced with +the replacement string. And in the replacement string, arg1 and arg2 +will be replaced with something1 and something2. +<p> +<dt><b> <font size=+1>B</font><font size=-1>UGS</font></b><dd> +Note that it is not a good idea to do something like this: +<p>#define foo bar // a comment +<p>The comment will be included in the define, and thus inserted in the +code. This will have the effect that the rest of the line will be +ignored when the word foo is used. Not exactly what you might expect. +<p> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=error> +<dl> +<dt><b> <font size=+1>D</font><font size=-1>IRECTIVE</font></b><dd> +<tt>#undef<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This removes the effect of a #define, all subsequent occurances of +the undefined identifier will not be replaced by anything. Note that +when undefining a macro, you just give the identifer, not the +arguments. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>#define foo bar<br> +#undef foo<br> +#define foo(bar) gazonk bar<br> +#undef foo<br> +<br> +</tt> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=error> +<dl> +<dt><b> <font size=+1>D</font><font size=-1>IRECTIVE</font></b><dd> +<tt>#if<br> +#elif<br> +#elseif<br> +#else<br> +#endif<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +The #if directive causes conditional compiling of code depending on +the expression after the #if directive. That is, if the expression +is true, the code up to the next #else, #elif, #elseif or #endif is +compiled. If the expression is false, that code will be skipped. +If the skip leads up to a #else, the code after the else will be +compiled. #elif and #elseif are equivialent and causes the code that +follow them to be compiled if the previous #if or #elif evaluated +false and the expression after the #elif evaluates true. +<p>Expressions given to #if, #elif or #endif are special, all identifiers +evaluate to zero unless they are defined to something else. Integers, +strings and floats are the only types that can be used, but all pike +operators can be used on these types. +<p>Also, two special functions can be used, defined() and constant(). +defined(<identifer>) expands to '1' if the identifier is defined, +'0' otherwise. constant(<identifier>) expands to '1' if identifer is +an predefined constant (with add_constant), '0' otherwise. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>#if 1<br> +<dl><dt><dd>write("foo");<br> +</dl>#else<br> +<dl><dt><dd>write("bar");<br> +</dl>#endif<br> + +<p>#if defined(FOO)<br> +<dl><dt><dd>write(FOO);<br> +</dl>#elif defined(BAR)<br> +<dl><dt><dd>write(BAR);<br> +</dl>#else<br> +<dl><dt><dd>write("default");<br> +</dl>#endif<br> + +<p>#if !constant(write_file)<br> +inherit "simulate.pike"<br> +#endif<br> +<br> +</tt> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=error> +<dl> +<dt><b> <font size=+1>D</font><font size=-1>IRECTIVE</font></b><dd> +<tt>#error<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This directive causes a compiler error, it can be used to notify +the user that certain functions are missing and similar things. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>#if !constant(write_file)<br> +#error write_file efun is missing<br> +#endif<br> +<br> +</tt> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=error> +<dl> +<dt><b> <font size=+1>D</font><font size=-1>IRECTIVE</font></b><dd> +<tt>#include<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This directive should be given a file as argument, it will then be +compiled as if all those lines were written at the #include line. +The compiler then continues to compile this file. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>#include "foo.h"<br> +<br> +</tt> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=error> +<dl> +<dt><b> <font size=+1>D</font><font size=-1>IRECTIVE</font></b><dd> +<tt>#line<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This directive tells the compiler what line and file we are compiling. +This is for instance used by the #include directive to tell the +compiler that we are compiling another file. The directive takes +the line number first, and optionally, the file afterwards. +<p>This can also be used when generating pike from something else, to +tell teh compiler where the code originally originated from. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>#line 4 "foo.cf" /* The next line was generated from 4 in foo.cf */<br> +<br> +</tt> +<p> +</dl> + +</a> +<hr noshade size=1> +<a name=error> +<dl> +<dt><b> <font size=+1>D</font><font size=-1>IRECTIVE</font></b><dd> +<tt>#pragma<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This is a generic directive for flags to the compiler. Currently, the +only flag available is 'all_inline' which is the same as adding the +modifier 'inline' to all functions that follows. + +<p> +</dl> + +</a> + +<ul> + <li> Comments: //, /* */ + <li> Substitution: #define, #undef + <li> Conditional: #if, #ifdef, #if defined(), #if efun(), #endif, #else, #elseif + <li> Including other files: #include "", #include <> + <li> Misc: #error, #pragma, #! +</ul> +<HR NEWPAGE> +<h1>11. All the builtin functions</h1> +This chapter is a reference for all the builtin functions in pike. +They are listed in alphabetical order. + +<HR NEWPAGE> +<a name=_memory_usage> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>_memory_usage</tt> - check memory usage +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mapping(string:int) <I>_memory_usage</I>();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is mostly intended for debugging. It delivers a mapping +with information about how many arrays/mappings/strings etc. there +are currently allocated and how much memory they use. Try evaluating +the function in hilfe to see precisly what it returns. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin__verify_internals.html>_verify_internals</a> +<p> +</dl> +</a> + + +<HR NEWPAGE> +<a name=_next> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>_next</tt> - find the next object/array/whatever +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed _next(mixed <I>p</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the 'next' object/array/mapping/string/etc +in the linked list. It is mainly meant for debugging Pike but +can also be used to control memory usage. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_next_object.html>next_object</a> and <a href=builtin__prev.html>_prev</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=_prev> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>_prev</tt> - find the previous object/array/whatever +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed _next(mixed <I>p</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the 'previous' object/array/mapping/etc +in the linked list. It is mainly meant for debugging Pike but +can also be used to control memory usage. Note that this function +does not work on strings. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin__next.html>_next</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=_refs> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>_refs</tt> - find out how many references a pointer type value has +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int _refs(string|array|mapping|multiset|function|object|program <I>o</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function checks how many references the value <i>o</i> has. +Note that the number of references will always be at least one since +it the value is located on the stack when this function is executed. +_refs() is mainly meant for debugging Pike but +can also be used to control memory usage. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#_next>_next</a> and <a href=#_prev>_prev</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=_verify_internals> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>_verify_internals</tt> - check Pike internals +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void _verify_internals();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function goes through most of the internal Pike structures and +generates a fatal error if one of them is found to be out of order. +It is only used for debugging. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +debugging +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=acos> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>acos</tt> - Trigonometrical inverse cosine +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float acos(float <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the arcus cosinus value for f. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_cos.html>cos</a> and <a href=math_asin.html>asin</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=add_constant> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>add_constant</tt> - add new predefined functions or constants +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void add_constant(string <I>name</I>, mixed <I>value</I>);<br> +or<br> +void add_constant(string <I>name</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function adds a new constant to Pike, it is often used to +add builin functions (efuns). All programs compiled after add_constant +function is called can access 'value' by the name given by 'name'. +If there is a constant called 'name' already, it will be replaced by +by the new definition. This will not affect already compiled programs. +<p>Calling add_constant without a value will remove that name from the list<br> +<dl><dt><dd><table border=0 cellpadding=0 cellspacing=0> +<tr valign=top><td> </td><td> of of constant. As with replacing, this will not affect already compiled </td></tr> +<tr valign=top><td> </td></tr> +</table> +</dl>programs.<br> + +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>add_constant("true",1);<br> +add_constant("false",0);<br> +add_constant("PI",4.0);<br> +add_constant("sqr",lambda(mixed x) { return x * x; });<br> +add_constant("add_constant");<br> +</tt> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_all_constants.html>all_constants</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=add_efun> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>add_efun</tt> - add an efun or constant +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>void add_efun(string func_name, mixed function)<br> +or<br> +void add_efun(string func_name)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is the same as add_constant. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_add_constant.html>add_constant</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=aggregage_list> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>aggregage_list</tt> - aggregate a multiset +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>multiset aggregage_list(mixed ... <I>args</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is exactly the same as aggregate_multiset. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_aggregage_multiset.html>aggregate_multiset</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=aggregate> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>aggregate</tt> - construct an array +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed *aggregate(mixed ... <I>elems</I>);<br> +or<br> +({ elem1, elem2, ... })<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Construct an array with the arguments as indices. This function +could be written in Pike as: +<p>mixed *aggregate(mixed ... elems) { return elems; } +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +Arrays are dynamically allocated there is no need to declare them +like int a[10]=allocate(10); (and it isn't possible either) like +in C, just int *a=allocate(10); will do. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_sizeof.html>sizeof</a>, <a href=builtin_arrayp.html>arrayp</a> and <a href=builtin_allocate.html>allocate</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=aggregate_mapping> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>aggregate_mapping</tt> - construct a mapping +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mapping aggregate_mapping(mixed ... <I>elems</I>);<br> +or<br> +([ key1:val1, key2:val2, ... ])<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Groups the arguments together two and two to key-index pairs and +creates a mapping of those pairs. The second syntax is always +preferable. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_mapping.html>mapping</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_sizeof.html>sizeof</a>, <a href=builtin_mappingp.html>mappingp</a> and <a href=builtin_mkmapping.html>mkmapping</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=aggregate_multiset> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>aggregate_multiset</tt> - construct a multiset +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>multiset aggregate_multiset(mixed ... <I>elems</I>);<br> +or<br> +(< elem1, elem2, ... >)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Construct an multiset with the arguments as indexes. This function +could be written in Pike as: +<p>multiset aggregate(mixed ... elems) { return mkmultiset(elems); } +<p>The only problem is that mkmultiset is implemented using +aggregage_multiset... +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_multiset.html>multiset</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_sizeof.html>sizeof</a>, <a href=builtin_multisetp.html>multisetp</a> and <a href=simulated_mkmultiset.html>mkmultiset</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=alarm> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>alarm</tt> - set an alarm clock for delivery of a signal +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int alarm(int <I>seconds</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +alarm arranges for a SIGALRM signal to be delivered to the +process in seconds seconds. +<p>If seconds is zero, no new alarm is scheduled. +<p>In any event any previously set alarm is cancelled. +<p> +<dt><b> <font size=+1>R</font><font size=-1>ETURN</font> <font size=+1>V</font><font size=-1>ALUE</font></b><dd> +alarm returns the number of seconds remaining until any +previously scheduled alarm was due to be delivered, or +zero if there was no previously scheduled alarm. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_signal.html>signal</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=all_constants> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>all_constants</tt> - return all predefined constants +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mapping (string:mixed) <I>all_constant</I>();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return a mapping containing all constants, indexed on the names of the +constant, and with the value of the efun as argument. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_add_constant.html>add_constant</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=all_efuns> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>all_efuns</tt> - return all 'efuns' +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>mapping all_efuns();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is the same as all_constants. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_all_constants.html>all_constants</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=allocate> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>allocate</tt> - allocate an array +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed *allocate(int <I>size</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Allocate an array of size elements and initialize them to zero. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>mixed *a=allocate(17);<br> +</tt> +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +Arrays are dynamically allocated there is no need to declare them +like int a[10]=allocate(10); (and it isn't possible either) like +in C, just int *a=allocate(10); will do. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_sizeof.html>sizeof</a>, <a href=builtin_aggregate.html>aggregate</a> and <a href=builtin_arrayp.html>arrayp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=arrayp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>arrayp</tt> - is the argument an array? +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int arrayp(mixed <I>arg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns 1 if arg is an array, zero otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_allocate.html>allocate</a>, <a href=builtin_intp.html>intp</a>, <a href=builtin_programp.html>programp</a>, <a href=builtin_floatp.html>floatp</a>, <a href=builtin_stringp.html>stringp</a>, <a href=builtin_objectp.html>objectp</a>, <a href=builtin_mappingp.html>mappingp</a>, <a href=builtin_multisetp.html>multisetp</a> and <a href=builtin_functionp.html>functionp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=asin> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>asin</tt> - Trigonometrical inverse sine +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float asin(float <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the arcus sinus value for f. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_sin.html>sin</a> and <a href=math_acos.html>acos</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=atan> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>atan</tt> - Trigonometrical inverse tangent +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float atan(float <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the arcus tangent value for f. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_tan.html>tan</a>, <a href=math_asin.html>asin</a> and <a href=math_acos.html>acos</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=backtrace> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>backtrace</tt> - get a description of the call stack +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed *backtrace();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns a description of the call stack at this moment. +The description is returned in an array with one entry for each call +in the stack. Each entry has this format: +<p>({<br> +<dl><dt><dd><table border=0 cellpadding=0 cellspacing=0> +<tr valign=top><td> file, </td><td> /* a string with the filename if known, else zero */ </td></tr> +<tr valign=top><td> line, </td><td> /* an integer containing the line if known, else zero */ </td></tr> +<tr valign=top><td> function, </td><td> /* The function-pointer to the called function */ </td></tr> +</table> +</dl>})<br> + +<p>The current call frame will be last in the array, and the one above +that the last but one and so on. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=pike_control_structures_catch.html>catch</a> and <a href=builtin_throw.html>throw</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=call_function> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>call_function</tt> - call a function with arguments +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed call_function(function <I>fun</I>,mixed ... <I>args</I>);<br> +or<br> +mixed fun ( mixed ... <I>args</I> );<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function takes a a function pointer as first argument and calls +this function with the rest of the arguments as arguments. Normally, +you will never have to write call_function(), because you will use the +second syntax instead. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_function.html>function</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_backtrace.html>backtrace</a> and <a href=simulated_get_function.html>get_function</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=call_out> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>call_out</tt> - make a delayed call to a function +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed call_out(function <I>f</I>, int <I>delay</I>, mixed ... <I>args</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Call_out places a call to the function f with the argument args +in a queue to be called in about delay seconds. The return value +identifies this call out. The return value can be sent to +find_call_out or remove_call_out to remove the call out again. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=call_out_remove_call_out.html>remove_call_out</a>, <a href=call_out_find_call_out.html>find_call_out</a> and <a href=call_out_call_out_info.html>call_out_info</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=call_out_info> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>call_out_info</tt> - get info about all call outs +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed **call_out_info();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns an array with one entry for each entry in the +call out queue. The first in the queue will be in index 0. Each index +contains an array that looks like this: +<p>({<br> +<dl><dt><dd><table border=0 cellpadding=0 cellspacing=0> +<tr valign=top><td> time_left, </td><td> /* an int */ </td></tr> +<tr valign=top><td> caller, </td><td> /* the object that made the call out */ </td></tr> +<tr valign=top><td> function, </td><td> /* the function to be called */ </td></tr> +<tr valign=top><td> arg1, </td><td> /* the first argument, if any */ </td></tr> +<tr valign=top><td> arg2, </td><td> /* the second argument, if any */ </td></tr> +<tr valign=top><td> ... </td><td> /* and so on... */ </td></tr> +</table> +</dl>})<br> + +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=call_out_call_out.html>call_out</a>, <a href=call_out_find_call_out.html>find_call_out</a> and <a href=call_out_remove_call_out.html>remove_call_out</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=capitalize> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>capitalize</tt> - capitalize a string +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>string capitalize(string str)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Convert the first character in str to upper case, and return the +new string. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_lower_case.html>lower_case</a> and <a href=builtin_upper_case.html>upper_case</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=catch> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>catch</tt> - catch errors +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>catch { commands }<br> +or<br> +catch ( expression )<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +catch traps exceptions such as run time errors or calls to throw() and +returns the argument given to throw. For a run time error, this value +is ({ "error message", backtrace }) +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#control>control</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_throw.html>throw</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<html><title>Pike: cd</title><body bgcolor="#A0E0C0" text="#000000" link=blue vlink=purple><a name=cd> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>cd</tt> - change directory +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int cd(string <I>s</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Change the current directory for the whole Pike process, return +1 for success, 0 otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_getcwd.html>getcwd</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=ceil> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>ceil</tt> - Truncate a number upward +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float ceil(float <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the closest integral value higher or equal to x. +Note that ceil() does _not_ return an int, merely an integral value. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_floor.html>floor</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=clone> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>clone</tt> - clone an object from a program +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object clone(program <I>p</I>,mixed ... <I>args</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +clone() creates an object from the program p. Or in C++ terms: +It creates an instance of the class p. This clone will first have +all global variables initalized, and then create() will be called +with args as arguments. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_object.html>object</a> and <a href=types_program.html>program</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_destruct.html>destruct</a>, <a href=builtin_compile_string.html>compile_string</a> and <a href=builtin_compile_file.html>compile_file</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=column> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>column</tt> - extract a column +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>array column(mixed *data,mixed index)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is exactly equivialent to: +<p>map_array(index,lambda(mixed x,mixed y) { return x[y]; },data) +<p>Except of course it is a lot shorter and faster. +That is, it indexes every index in the array data on the value of +the argument index and returns an array with the results. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_rows.html>rows</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=combine_path> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>combine_path</tt> - concatenate paths +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string combine_path(string <I>absolute</I>, string <I>relative</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Concatenate a relative path to an absolute path and remove any +"//", "/.." or "/." to produce a straightforward absolute path +as a result. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>> combine_path("/foo/bar/","..");<br> +Result: /foo<br> +> combine_path("/foo/bar/","../apa.c");<br> +Result: /foo/apa.c<br> +> combine_path("/foo/bar","./sune.c");<br> +Result: /foo/bar/sune.c<br> +</tt> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_getcwd.html>getcwd</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=compile_file> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>compile_file</tt> - compile a file to a program +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>program compile_file(string <I>filename</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function will compile the filename to an Pike program that can +later be used for cloning. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_program.html>program</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_clone.html>clone</a> and <a href=builtin_compile_string.html>compile_string</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=compile_string> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>compile_string</tt> - compile a string to a program +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>program compile_string(string <I>prog</I>, string <I>name</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Compile_string takes a complete Pike program as an argument in a the +string prog and compiles it to clonable program. The second argument +will be used as the file name of the program and will be used for +error messages and such. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_program.html>program</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_compile_string.html>compile_string</a> and <a href=builtin_clone.html>clone</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=copy_value> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>copy_value</tt> - copy a value recursively +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed copy_value(mixed <I>value</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Copy value will copy the value given to it recursively. If the result +value is changed destructively (only possible for multisets, arrays and +mappings) the copied value will not be changed. The resulting value +will always be equal to the copied (tested with the efun equal), but +they may not the the same value. (tested with ==) +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_equal.html>equal</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=cos> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>cos</tt> - Trigonometrical cosine +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float cos(float <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the cosinus value for f. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_acos.html>acos</a> and <a href=math_sin.html>sin</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +html><title>Pike: crypt</title><body bgcolor="#A0E0C0" text="#000000" link=blue vlink=purple><a name=crypt> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>crypt</tt> - crypt a password +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string crypt(string <I>password</I>);<br> +or<br> +int crypt(string <I>typed_password</I>, string <I>crypted_password</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function crypts and verifies a short string. (normally only +the first 8 characters are significant) The first syntax crypts +the string password into something that is hopefully hard to decrypt, +and the second function crypts the first string and verifies that the +crypted result matches the second argument and returns 1 if they +matched, 0 otherwise. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>To crypt a password use:<br> +<dl><dt><dd>crypted_password = crypt(typed_password);<br> +</dl>To see if the same password was used again use:<br> +<dl><dt><dd>matched = crypt(typed_password, crypted_password);<br> +</dl> +</tt> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +</dl> + +</a> +<HR NEWPAGE> +<a name=ctime> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>ctime</tt> - convert time int to readable date string +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string ctime(int <I>current_time</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Convert the output from a previous call to time() into a readable +string containing the currnent year, month, day and time. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>> ctime(time());<br> +Result: Wed Jan 14 03:36:08 1970<br> +</tt> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_time.html>time</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=describe_backtrace> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>describe_backtrace</tt> - make a backtrace readable +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>string describe_backtrace(mixed **<I>backtrace</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Describe backtrace returns a string containing a readable message +that describes where the backtrace was made. The argument 'backtrace' +should normally be the return value from a call to backtrace() +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_backtrace.html>backtrace</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=destruct> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>destruct</tt> - destruct an object +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void destruct(object <I>o</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Destruct marks an object as destructed, all pointers and function +pointers to this object will become zero. The destructed object will +be freed from memory as soon as possible. This will also call +o->destroy. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_object.html>object</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_clone.html>clone</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=equal> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>equal</tt> - check if two values are equal or not +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int equal(mixed <I>a</I>, mixed <I>b</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function checks if the values a and b are equal. For all types but +arrays, multisets and mappings, this operation is the same as doing a == b. +For arrays, mappings and multisets however, their contents are checked +recursively, and if all their contents are the same and in the same +place, they are considered equal. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>> ({ 1 }) == ({ 1 });<br> +Result: 0<br> +> equal( ({ 1 }), ({ 1 }) );<br> +Result: 1<br> +> <br> +</tt> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_copy_value.html>copy_value</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=errno> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>errno</tt> - return system error number +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int errno();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the system error from the last file operation. +Note that you should normally use the function errno in the file +object instead. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_errno.html>errno</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=exec> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>exec</tt> - simple way to use exece() +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <process.h><br> + +<p>int exec(string <I>file</I>, string ... <I>args</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function destroys the Pike parser and runs the program +'file' instead with the arguments. If no there are no '/' in +the filename, the variable PATH will be consulted when looking +for the program. This function does not return except when +the exec fails for some reason. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>exec("/bin/echo","hello","world");<br> +<br> +</tt> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=exece> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>exece</tt> - execute a program +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int exece(string <I>file</I>, string *<I>args</I>);<br> +or<br> +int exece(string <I>file</I>, string *<I>args</I>, mapping(string:string) <I>env</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function transforms the Pike process into a process running +the program specified in the argument 'file' with the argument 'args'. +If the mapping 'env' is present, it will completely replace all +environment variables before the new program is executed. +This function only returns if something went wrong during exece(), +and in that case it returns zero. +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +The Pike driver _dies_ when this function is called. You must use +fork() if you wish to execute a program and still run the Pike +driver. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>exece("/bin/ls", ({"-l"}));<br> +exece("/bin/sh", ({"-c", "echo $HOME"}), (["HOME":"/not/home"]));<br> +</tt> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_fork.html>fork</a> and <a href=files_file.html#pipe>file->pipe</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=exit> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>exit</tt> - exit Pike interpreter +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void exit(int <I>returncode</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function exits the whole 'pike' program with the return code +given. Using exit() with any other value than 0 indicates that +something went wrong during execution. See your system manuals for +more information about return codes. + +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=exp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>exp</tt> - Natural exponent +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float exp(float <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the natural exponent of f. +log( exp( x ) ) == x as long as exp(x) doesn't overflow an int. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_pow.html>pow</a> and <a href=math_log.html>log</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=explode> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>explode</tt> - explode a string on a delimeter +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>string *explode(string <I>victim</I>, string <I>delimeter</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Explode divides the string called victim at every occurance of +the string delimeter and returns the resulting parts in an array. +If delimeter is an empty string, victim will be divided into strings +of length 1. +<p>Explode is the same as division. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>> explode("foobar","o");<br> +Result: ({ "f", "", "bar" })<br> +> explode("10101001010100010101","10");<br> +Result: ({ "", "", "", "0", "", "", "00", "", "1" })<br> +> explode("/foo/bar/gazonk","/");<br> +Result: ({ "", "foo", "bar", "gazonk" })<br> +> explode("foobar","");<br> +Result: ({ "f", "o", "o", "b", "a", "r" })<br> +</tt> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_implode.html>implode</a> and <a href=operators_divide.html>`/</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=file_size> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>file_size</tt> - return the size of a file in bytes +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <stdio.h><br> + +<p>int file_size(string <I>file</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Give the size of a file. Size -1 indicates that the file either +does not exist, or that it is not readable by you. Size -2 +indicates that it is a directory. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_write_file.html>write_file</a> and <a href=simulated_read_bytes.html>read_bytes</a> +<p> +</dl> +</a> + + +<HR NEWPAGE> +<a name=file_stat> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>file_stat</tt> - stat a file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int *file_stat(string <I>file</I>);<br> +or<br> +int *file_stat(string <I>file</I>, <I>1</I>);<br> +or<br> +int *file->stat();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +file_stat returns an array of integers describing some properties<br> +about the file. Currently file_stat returns 7 entries:<br> +({<br> +<dl><dt><dd><table border=0 cellpadding=0 cellspacing=0> +<tr valign=top><td> mode, </td><td> /* file mode, protection bits etc. etc. */ </td></tr> +<tr valign=top><td> size, </td><td> /* file size for regular files, -2 for dirs, -3 for links, -4 for otherwise */ </td></tr> +<tr valign=top><td> atime, </td><td> /* last access time */ </td></tr> +<tr valign=top><td> mtime, </td><td> /* last modify time */ </td></tr> +<tr valign=top><td> ctime, </td><td> /* last status time change */ </td></tr> +<tr valign=top><td> uid, </td><td> /* The user who owns this file */ </td></tr> +<tr valign=top><td> gid </td><td> /* The group this file belongs to */ </td></tr> +</table> +</dl>})<br> +If you give 1 as a second argument, file_stat does not follow links.<br> +You can never get -3 as size if you don't give a second argument.<br> + +<p>If there is no such file or directory, zero is returned. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_get_dir.html>get_dir</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=filter> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>filter</tt> - filter an array or mapping through a function +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <array.h><br> + +<p>mixed *filter(mixed <I>arr</I>,function <I>fun</I>,mixed ... <I>args</I>);<br> +or<br> +mixed *filter(object *<I>arr</I>,string <I>fun</I>,mixed ... <I>args</I>);<br> +or<br> +mixed *filter(function *<I>arr</I>,-<I>1</I>,mixed ... <I>args</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +First syntax: +Filter array returns an array holding the items of arr for which +fun returns true. +<p>Second syntax: +Filter array calls fun in all the objects in the array arr, and +return all objects that returned true. +<p>Third syntax: +Filter array calls all functionpointers in the array arr, and +return all that returned true. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_sum_arrays.html>sum_arrays</a> and <a href=simulated_map.html>map</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=filter_array> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>filter_array</tt> - filter an array through a function +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>mixed *filter_array(mixed *<I>arr</I>,function <I>fun</I>,mixed ... <I>args</I>);<br> +or<br> +mixed *filter_array(object *<I>arr</I>,string <I>fun</I>,mixed ... <I>args</I>);<br> +or<br> +mixed *filter_array(function *<I>arr</I>,-<I>1</I>,mixed ... <I>args</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Filter array is the same function as filter. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_sum_arrays.html>sum_arrays</a>, <a href=simulated_map_array.html>map_array</a> and <a href=simulated_filter.html>filter</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=find_call_out> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>find_call_out</tt> - find a call out in the queue +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int find_call_out(function <I>f</I>);<br> +or<br> +int find_call_out(mixed <I>id</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function searches the call out queue. If given a function as +argument, it looks for the first call out scheduled to that function. +The argument can also be a call out id as returned by call_out, in +which case that call_out will be found. (Unless it has already been +called.) find_call_out will then return how many seconds remains +before that call will be executed. If no call is found, +zero_type(find_call_out(f)) will return 1. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=call_out_call_out.html>call_out</a>, <a href=call_out_remove_call_out.html>remove_call_out</a> and <a href=call_out_call_out_info.html>call_out_info</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=find_option> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>find_option</tt> - find command line options +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <getopt.h><br> + +<p>mixed find_option(string *argv,<br> +<dl><dt><dd>string shortform,<br> +string longform,<br> +string envvar,<br> +mixed def);<br> +</dl></tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This is a generic function to parse command line options of the +type '-f', '--foo' or '--foo=bar'. The first argument should be +the array of strings that is sent as second argument to your +main() function, the second is a string with the short form of +your option. The short form must be only one character long. +The 'longform' is an alternative and maybe more readable way to +give the same option. If you give "foo" as longform your program +will accept --foo as argument. The envvar argument specifies what +environment variable can be used to specify the same option. The +envvar option exists to make it easier to custimizer program usage. +The 'def' has two functions: It specifies that the option takes an +argument and it tells find_option what to return if the option is +not present. If 'def' is given and the option does not have an +argument find_option will print an error message and exit the program. +<p>Also, as an extra bonus: shortform, longform and envvar can all be +arrays, in which case either of the options in the array will be +accpted. +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +find_option modifies argv. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>int main(int argc, string *argv)<br> +{<br> +<dl><dt><dd>if(find_option(argv,"f","foo"))<br> +<dl><dt><dd>werror("The FOO option was given.\n");<br> +</dl></dl> +<p><dl><dt><dd>werror("The BAR option got the "+<br> +find_option(argv,"b","bar","BAR_OPTION","default")+<br> +" argument.\n");<br> +</dl>}<br> +</tt> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_get_args.html>get_args</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=find_all_options> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>find_all_options</tt> - find all command line options +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <getopt.h><br> + +<p>array(array(mixed)) find_option(string *argv,<br> +<dl><dt><dd>array(array(mixed)) options,<br> +[ int posix_me_harder ]);<br> +</dl></tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This is a generic function to parse command line options of the +type '-f', '--foo' or '--foo=bar'. The first argument should be +the array of strings that is sent as second argument to your +main() function. The second argument is an array describing all +options your program accepts. The third argument is optional, if +the third argument is 0 or not given, find_all_options will look +though the whole command line after options, otherwise it will +only look until it finds a somthing that does not begin with '-'. +The second argument an array, where each element is an array on +the following format: +<tt> +<p> +<dl><dt><dd>({<br> + <dl><dt><dd> + <i>name</i>, // A string identifying the option<br> + <i>type</i>, // Does the oprion need an argument <br> + <i>option</i>, // The actual option<br> + <i>environmen variable</i>,<br> + <i>default</i> // Use this if option not specified<br></dl> + })</dl> +<p> +</tt> +Only the three first indexes in this array are needed, the last +two are optional. The <i>name</i> is a string, it is not actually +used in parsing the options, but rather in the return value to +identify which option was found. The <i>type</i> is one of +<tt>HAS_ARG</tt>, <tt>NO_ARG</tt> and <tt>MAY_HAVE_ARG</tt>. +<tt>HAS_ARG</tt> means that an error will be given if no argument +was given for the option. <tt>NO_ARG</tt> means that no arguments +will be expected for this option. <tt>MAY_HAVE_ARG</tt> means +that any argument found will be returned, but if there is no +argument no error message will be generated. <i>option</i> should +be a an array of string, each of these strings contain one +<b>longform</b> (<tt>"--<i>option</i>"</tt>) or several +<b>shortforms</b> (<tt>"-<i>shortforms</i></tt>) for the option. +If they array contains only one string, the string can be given +directly for <i>option</i>. If the option is not specified on +the command line, the <i>environment variable</i> will be consulted. +If that environment variable is set, the contents of that environment +variable will be used as argument for this option. +The <i>environment variable<i> can also be an array of variables to +look for.</i> If the option was not on the command line, and not +in any environment variable, the <i>default</i> value will be returned. +<p> +This function returns an array in which each element is an array +of the following form: + +<tt><dl><dt><dd>({<i>name</i>, <i>value</i>})</dl></tt> + +<i>Name<i> is the same as given in the array of options, and <i> +value</i> is a string if any value was given for the option, <tt>1</tt> +otherwise. +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +find_option modifies argv. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>int main(int argc, string *argv)<br> +{<br> + <dl><dt><dd> + array(array) options=find_all_option(argv,({"version",NO_ARG,({"-vV","--version"}) }), 1);<br> + foreach(options, array option)<br> + {<br> + <dl><dt><dd> + switch(option[0])<br> + {<br> + case "version":<br> + <dl><dt><dd> + write("Running "+version+".\n");<br> + exit(0);<br> + </dl> + }<br> + </dl> + }<br> + </dl> +}<br> +</tt> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=#get_args>get_args</a> and <a href=#find_options>find_option</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=floatp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>floatp</tt> - is the argument an float? +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int floatp(mixed <I>arg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns 1 if arg is a float, zero otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_intp.html>intp</a>, <a href=builtin_programp.html>programp</a>, <a href=builtin_arrayp.html>arrayp</a>, <a href=builtin_stringp.html>stringp</a>, <a href=builtin_objectp.html>objectp</a>, <a href=builtin_mappingp.html>mappingp</a>, <a href=builtin_multisetp.html>multisetp</a> and <a href=builtin_functionp.html>functionp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=floor> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>floor</tt> - Truncate a number downward +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float floor(float <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the closest integral value lower or equal to x. +Note that floor() does _not_ return an int, merely an integral value. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_ceil.html>ceil</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=fork> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>fork</tt> - fork the process in two +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int fork();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Fork splits the process in two, and for the parent it returns the +pid of the child. Refer to your unix manual for further details. +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +This function cause endless bugs if used without proper care. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_exec.html>exec</a> and <a href=files_file.html#pipe>file->pipe</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=function_name> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>function_name</tt> - return the name of a function, if known +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string function_name(function <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the name of the function f. If the function is +a pre-defined function in the driver, zero will be returned. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_function.html>function</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_function_object.html>function_object</a> and <a href=simulated_get_function.html>get_function</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=function_object> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>function_object</tt> - return what object a function is in +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object function_object(function <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Function_object will return the object the function f is in. If the +function is a predefined function from the driver, zero will be +returned. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_function.html>function</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_function_name.html>function_name</a> and <a href=simulated_get_function.html>get_function</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=functionp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>functionp</tt> - is the argument an function? +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int functionp(mixed <I>arg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns 1 if arg is a function, zero otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_function.html>function</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_intp.html>intp</a>, <a href=builtin_programp.html>programp</a>, <a href=builtin_arrayp.html>arrayp</a>, <a href=builtin_stringp.html>stringp</a>, <a href=builtin_objectp.html>objectp</a>, <a href=builtin_mappingp.html>mappingp</a>, <a href=builtin_multisetp.html>multisetp</a> and <a href=builtin_floatp.html>floatp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=gauge> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>gauge</tt> - measure system time +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>gauge { commands }<br> +or<br> +gauge ( expression )<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Gauge measure how much cpu time is used to execute the commands +given as arguments. The number of milliseconds used is returned +as an integer. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#control>control</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=pike_control_structures_catch.html>catch</a> and <a href=builtin_rusage.html>rusage</a> +<p> +</dl> + +<HR NEWPAGE> +html><title>Pike: gc</title><body bgcolor="#A0E0C0" text="#000000" link=blue vlink=purple><a name=gc> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>gc</tt> - do garbage collection +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int gc();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function checks all the memory for cyclic structures such +as arrays containing themselves and frees them if approperiate. +It also frees up destructed objects. It then returns how many +arrays/objects/programs/etc. it managed </td><td> to free by doing this. +Normally there is no need to call this function since Pike will +call it by itself every now and then. (Pike will try to predict +when 20% of all arrays/object/programs in memory is 'garbage' +and call this routine then.) +</table> + +</dl> +</a> + + +<HR NEWPAGE> +<a name=get_args> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>get_args</tt> - get the non-option arguments +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <getopt.h><br> + +<p>string *get_args(string *<I>argv</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the remaining command line arguments after +you have run find_options to find all the options in the +argument list. If there are any options left not handled by +find_options an error message will be written and the program will +exit. Otherwise a new 'argv' array without the parsed options is +returned. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>int main(int argc, string *argv)<br> +{<br> +<dl><dt><dd>if(find_option(argv,"f","foo"))<br> +<dl><dt><dd>werror("The FOO option was given.\n");<br> +</dl></dl> +<p><dl><dt><dd>argv=get_args(argv);<br> +werror("The arguments are: "+(argv*" ")+".\n");<br> +</dl>}<br> +</tt> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_find_option.html>find_option</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=get_dir> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>get_dir</tt> - read a directory +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string *get_dir(string <I>dirname</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return an array of all filenames in the directory dir, or zero if +no such directory exists. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_mkdir.html>mkdir</a> and <a href=files_cd.html>cd</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=get_function> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>get_function</tt> - fetch a function from an object +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>function get_function(object <I>o</I>, string <I>name</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Defined as: return o[name]; +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_function.html>function</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=getcwd> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>getcwd</tt> - return current working directory +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string getcwd();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +getcwd returns the current working directory. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_cd.html>cd</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=getenv> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>getenv</tt> - get an environment variable +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string getenv(string <I>varname</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Reurns the value of the environment variable with the name varname, +if no such environment variable exists, zero is returned. +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +This function is provided by master.c +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=getpid> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>getpid</tt> - get the process id of this process +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int getpid();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This returns the pid of this process. Useful for sending +signals to yourself. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_kill.html>kill</a>, <a href=files_fork.html>fork</a> and <a href=builtin_signal.html>signal</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=glob> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>glob</tt> - match strings against globs +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int glob(string <I>glob</I>, string <I>str</I>);<br> +or<br> +string *glob(string <I>glob</I>, string *<I>arr</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function matches "globs". A in the glob string a question sign +matches any character and an asterisk matches any string. When +given two strings as argument a true/false value is returned +which reflects if the 'str' matches 'glob'. When given an array as +second argument, an array containing all matching strings is returned. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=pike_sscanf.html>sscanf</a> and <a href=simulated_regexp.html>regexp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=hash> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>hash</tt> - hash a string +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int hash(string <I>s</I>);<br> +or<br> +int hash(string <I>s</I>, int <I>max</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function will return an int derived from the string s. The same +string will always hash to the same value. If a second argument +is given, the result will be >= 0 and lesser than that argument. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=implode> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>implode</tt> - implode an array of strings +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>string implode(string *<I>a</I>, string <I>delimeter</I>);<br> +or<br> +a * delimeter<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is the inverse of explode. It contatenates all the +strings in a with a delimeter in between each. +<p>This function is the same as multiplication. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>> implode( ({ "foo","bar","gazonk"}), "-" );<br> +Result: foo-bar-gazonk<br> +> ({ "a","b","c" })*" and ";<br> +Result: a and b and c<br> +> <br> +</tt> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_explode.html>explode</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=implode_nicely> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>implode_nicely</tt> - make an english comma separated list +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <string.h><br> + +<p>string implode_nicely(string *words, string|void separator)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function implodes a list of words to a readable string. +If the separator is omitted, the default is 'and'. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>> implode_nicely(({"green"}));<br> +Result: green<br> +> implode_nicely(({"green","blue"}));<br> +Result: green and blue<br> +> implode_nicely(({"green","blue","white"}));<br> +Result: green, blue and white<br> +> implode_nicely(({"green","blue","white"}),"or");<br> +Result: green, blue or white<br> +</tt> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=operators_mult.html>`*</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=indices> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>indices</tt> - return an array of all index possible for a value +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed *indices(string|array|mapping|multiset|object <I>foo</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Indices returns an array of all values you can use as index when +indexing foo. For strings and arrays this is simply an array of the +ascending numbers. For mappings and multisets, the array may contain any +kind of value. For objects, the result is an array of strings. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_mapping.html>mapping</a> and <a href=types_multiset.html>multiset</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_values.html>values</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=intp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>intp</tt> - is the argument an int? +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>array intp(mixed <I>arg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns 1 if arg is an int, zero otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_int.html>int</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_arrayp.html>arrayp</a>, <a href=builtin_programp.html>programp</a>, <a href=builtin_floatp.html>floatp</a>, <a href=builtin_stringp.html>stringp</a>, <a href=builtin_objectp.html>objectp</a>, <a href=builtin_mappingp.html>mappingp</a>, <a href=builtin_multisetp.html>multisetp</a> and <a href=builtin_functionp.html>functionp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=kill> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>kill</tt> - send signal to other process +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int kill(int pid, int signal)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Kill sends a signal to another process. If something goes wrong +-1 is returned, 0 otherwise. +<p>Some signals and their supposed purpose: +<p><table border=0 cellpadding=0 cellspacing=0> +<tr valign=top><td> SIGHUP </td><td> Hangup, sent to process when user logs out </td></tr> +<tr valign=top><td> SIGINT </td><td> Interrupt, normally sent by ctrl-c </td></tr> +<tr valign=top><td> SIGQUIT </td><td> Quit, sent by ctrl-\ </td></tr> +<tr valign=top><td> SIGILL </td><td> Illegal instruction </td></tr> +<tr valign=top><td> SIGTRAP </td><td> Trap, mostly used by debuggers </td></tr> +<tr valign=top><td> SIGABRT </td><td> Aborts process, can be caught, used by Pike whenever something goes seriously wrong. </td></tr> +<tr valign=top><td> SIGBUS </td><td> Bus error </td></tr> +<tr valign=top><td> SIGFPE </td><td> Floating point error (such as division by zero) </td></tr> +<tr valign=top><td> SIGKILL </td><td> Really kill a process, cannot be caught </td></tr> +<tr valign=top><td> SIGUSR1 </td><td> Signal reserved for whatever you want to use it for. </td></tr> +<tr valign=top><td> SIGSEGV </td><td> Segmentation fault, caused by accessing memory where you shouldn't. Should never happen to Pike. </td></tr> +<tr valign=top><td> SIGUSR2 </td><td> Signal reserved for whatever you want to use it for. </td></tr> +<tr valign=top><td> SIGALRM </td><td> Signal used for timer interrupts. </td></tr> +<tr valign=top><td> SIGTERM </td><td> Termination signal </td></tr> +<tr valign=top><td> SIGSTKFLT </td><td> Stack fault </td></tr> +<tr valign=top><td> SIGCHLD </td><td> Child process died </td></tr> +<tr valign=top><td> SIGCONT </td><td> Continue suspended </td></tr> +<tr valign=top><td> SIGSTOP </td><td> Stop process </td></tr> +<tr valign=top><td> SIGSTP </td><td> Suspend process </td></tr> +<tr valign=top><td> SIGTTIN </td><td> tty input for background process </td></tr> +<tr valign=top><td> SIGTTOU </td><td> tty output for background process </td></tr> +<tr valign=top><td> SIGXCPU </td><td> Out of cpu </td></tr> +<tr valign=top><td> SIGXFSZ </td><td> File size limit exceeded </td></tr> +<tr valign=top><td> SIGPROF </td><td> Profile trap </td></tr> +<tr valign=top><td> SIGWINCH </td><td> Window change signal </td></tr> +</table> + +<p>Note that you have to use signame to translate the name of a signal +to it's number. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_signal.html>signal</a>, <a href=builtin_signum.html>signum</a>, <a href=builtin_signame.html>signame</a> and <a href=files_fork.html>fork</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=l_sizeof> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>l_sizeof</tt> - Return the size of a multiset +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>int l_sizeof(multiset <I>m</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is equal to sizeof. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_multiset.html>multiset</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_sizeof.html>sizeof</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=listp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>listp</tt> - is the argument a list? (multiset) +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>int listp(mixed l)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is the same as multisetp. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_multisetp.html>multisetp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=load_module> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>load_module</tt> - load a binary module +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int load_module(string <I>module_name</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function loads a module written in C or some other language +into Pike. The module is initialized and any programs or constants +defined will immediately be available. +<p>When a module is loaded the functions init_module_efuns and +init_module_programs are called to initialize it. When Pike exits +exit_module is called in all dynamically loaded modules. These +functions _must_ be available in the module. +<p>Please see the source and any examples available at +ftp://www.infovav.se/pub/pike for more information on how to +write modules for Pike in C. +<p> +<dt><b> <font size=+1>B</font><font size=-1>UGS</font></b><dd> +Please use "./name.so" instead of just "foo.so" for the module +name. If you use just "foo.se" the module will not be found. + +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=localtime> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>localtime</tt> - break down time() into intelligible components +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mapping(string:int) localtime(int <I>time</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Given a time represented as second since 1970, as returned by the +function time(), this function returns a mapping with the following +components: +<p><table border=0 cellpadding=0 cellspacing=0> +<tr valign=top><td> sec </td><td> seconds over the minute </td><td> 0 - 59 </td></tr> +<tr valign=top><td> min </td><td> minutes over the hour </td><td> 0 - 59 </td></tr> +<tr valign=top><td> hour </td><td> what hour in the day </td><td> 0 - 23 </td></tr> +<tr valign=top><td> mday </td><td> day of the month </td><td> 1 - 31 </td></tr> +<tr valign=top><td> mon </td><td> what month </td><td> 0 - 11 </td></tr> +<tr valign=top><td> year </td><td> years since 1900 </td><td> 0 - </td></tr> +<tr valign=top><td> wday </td><td> day of week (0=sunday) </td><td> 0 - 6 </td></tr> +<tr valign=top><td> yday </td><td> day of year </td><td> 0 - 365 </td></tr> +<tr valign=top><td> isdst </td><td> is daylight saving time </td><td> 0/1 </td></tr> +<tr valign=top><td> timezone </td><td> differance between </td></tr> +<tr valign=top><td> </td><td> </td><td> local time and UTC </td></tr> +</table> + +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +The 'timezone' might not be available on all platforms. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_time.html>time</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=log> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>log</tt> - Natural logarithm +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float log(float <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the natural logarithm of f. +exp( log(x) ) == x for x > 0. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_pow.html>pow</a> and <a href=math_exp.html>exp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=lower_case> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>lower_case</tt> - convert a string to lower case +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string lower_case(string <I>s</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return a string with all capital letters converted to lower case. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_upper_case.html>upper_case</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=m_delete> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>m_delete</tt> - remove an index from a mapping +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mapping m_delete(mapping <I>map</I>, mixed <I>index</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Remove the entry with index 'index' from mapping 'map' destructively. +Return the changed mapping. If the mapping does not have an +entry with index 'index', nothing is done. +Note that m_delete changes map destructively and only returns +the mapping for compatibility reasons. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_mapping.html>mapping</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_mappingp.html>mappingp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=m_indices> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>m_indices</tt> - return all indices from a mapping +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>mixed *m_indices(mapping <I>m</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is equal to indices +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_mapping.html>mapping</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_indices.html>indices</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=m_sizeof> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>m_sizeof</tt> - Return the size of a mapping +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>int m_sizeof(mapping <I>m</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is equal to sizeof. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_mapping.html>mapping</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_sizeof.html>sizeof</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=m_values> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>m_values</tt> - return all values from a mapping +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>mixed *m_values(mapping <I>m</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is equal to values +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_mapping.html>mapping</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_values.html>values</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=map> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>map</tt> - map an array or mapping over a function +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed *map(mixed <I>arr</I>,function <I>fun</I>,mixed ... <I>args</I>);<br> +or<br> +mixed *map(object *<I>arr</I>,string <I>fun</I>,mixed ... <I>args</I>);<br> +or<br> +mixed *map(function *<I>arr</I>,-<I>1</I>,mixed ... <I>arg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +First syntax: +Map array returns an array holding the items of arr mapped thrugh +the function fun. ie. arr[x]=fun(arr[x], @args) for all x. +<p>Second syntax: +Map array calls function fun in all objects in the array arr. +ie. arr[x]=arr[x]->fun(@ args); +<p>Third syntax: +Map array calls the functions in the array arr: +arr[x]=arr[x]->fun(@ args); +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_sum_arrays.html>sum_arrays</a> and <a href=simulated_filter.html>filter</a> +<p> +</dl> +</a> + + +<HR NEWPAGE> +<a name=map_array> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>map_array</tt> - map an array over a function +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed *map_array(mixed *<I>arr</I>,function <I>fun</I>,mixed ... <I>args</I>);<br> +or<br> +mixed *map_array(object *<I>arr</I>,string <I>fun</I>,mixed ... <I>args</I>);<br> +or<br> +mixed *map_array(function *<I>arr</I>,-<I>1</I>,mixed ... <I>arg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is the same as map. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_filter_array.html>filter_array</a>, <a href=simulated_sum_arrays.html>sum_arrays</a> and <a href=simulated_map.html>map</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=mappingp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>mappingp</tt> - is the argument an mapping? +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int mappingp(mixed <I>arg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns 1 if arg is a mapping, zero otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_mapping.html>mapping</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_intp.html>intp</a>, <a href=builtin_programp.html>programp</a>, <a href=builtin_arrayp.html>arrayp</a>, <a href=builtin_stringp.html>stringp</a>, <a href=builtin_objectp.html>objectp</a>, <a href=builtin_multisetp.html>multisetp</a>, <a href=builtin_floatp.html>floatp</a> and <a href=builtin_functionp.html>functionp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=master> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>master</tt> - return the master object +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object master();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Master is added by the master object to make it easier to access it. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_object.html>object</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=member_array> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>member_array</tt> - find first occurance of a value in an array +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>int member_array(mixed <I>item</I>, mixed *<I>arr</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns the index of the first occurence of item in array arr. +If not found, then -1 is returned. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=mkdir> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>mkdir</tt> - make directory +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int mkdir(string <I>dirname</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Create a directory, return zero if it fails and nonzero if it fails. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_rm.html>rm</a> and <a href=files_cd.html>cd</a> +<p> +</dl> +</a> + + +<HR NEWPAGE> +<a name=mklist> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>mklist</tt> - make a multiset +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>multiset mklist(mixed *a)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function creates a multiset from an array. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>> mklist( ({1,2,3}) );<br> +Result: (< /* 3 elements */<br> +<dl><dt><dd>1,<br> +2,<br> +3<br> +</dl>>)<br> +</tt> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_multiset.html>multiset</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_aggregage_multiset.html>aggregate_multiset</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=mkmapping> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>mkmapping</tt> - make a mapping from two arrays +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mapping mkmapping(mixed *<I>ind</I>, mixed *<I>val</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Makes a mapping ind[x]:val[x], 0<=x<sizeof(ind). +Ind and val must have the same size. +This is the inverse operation of indices and values. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_mapping.html>mapping</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_indices.html>indices</a> and <a href=builtin_values.html>values</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=mkmultiset> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>mkmultiset</tt> - make a multiset +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>multiset mkmultiset(mixed *a)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function creates a multiset from an array. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>> mkmultiset( ({1,2,3}) );<br> +Result: (< /* 3 elements */<br> +<dl><dt><dd>1,<br> +2,<br> +3<br> +</dl>>)<br> +</tt> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_multiset.html>multiset</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_aggregage_multiset.html>aggregate_multiset</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=multisetp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>multisetp</tt> - is the argument a multiset? +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int multisetp(mixed <I>arg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns 1 if arg is a multiset, zero otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_multiset.html>multiset</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_intp.html>intp</a>, <a href=builtin_programp.html>programp</a>, <a href=builtin_arrayp.html>arrayp</a>, <a href=builtin_stringp.html>stringp</a>, <a href=builtin_objectp.html>objectp</a>, <a href=builtin_mappingp.html>mappingp</a>, <a href=builtin_floatp.html>floatp</a> and <a href=builtin_functionp.html>functionp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=mv> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>mv</tt> - move a file (may handle directiories as well) +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int mv(string <I>from</I>,string <I>to</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Rename or move a file between directories. If the destination +file already exists, it will be overwritten. Returns 1 on sucess, +0 otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_rm.html>rm</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=next_object> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>next_object</tt> - get next object +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object next_object(object <I>o</I>);<br> +or<br> +object next_object();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +All objects are stored in a linked list, next_object() returns the +first object in this list, and next_object(o) the next object in the +list after o. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>/* This example calls shutting_down() in all cloned objects */<br> +object o;<br> +for(o=next_object();o;o=next_object(o))<br> +<dl><dt><dd>o->shutting_down();<br> +</dl></tt> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_object.html>object</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_clone.html>clone</a> and <a href=builtin_destruct.html>destruct</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=object_program> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>object_program</tt> - get the program asociated with the object +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>program object_program(object <I>o</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the program from which o was cloned. +If o is not an object, or o was destructed zero is returned. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_object.html>object</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_clone.html>clone</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=objectp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>objectp</tt> - is the argument an object? +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int objectp(mixed <I>arg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns 1 if arg is an object, zero otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_object.html>object</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_intp.html>intp</a>, <a href=builtin_programp.html>programp</a>, <a href=builtin_floatp.html>floatp</a>, <a href=builtin_stringp.html>stringp</a>, <a href=builtin_arrayp.html>arrayp</a>, <a href=builtin_mappingp.html>mappingp</a>, <a href=builtin_multisetp.html>multisetp</a> and <a href=builtin_functionp.html>functionp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=perror> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>perror</tt> - print error +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <stdio.h><br> + +<p>void perror(string <I>s</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function prints a message to stderr along with a description +of what went wrong if available. It uses the system errno to find +out what went wrong, so it is only applicable to IO errors. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_werror.html>werror</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=popen> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>popen</tt> - pipe open +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <process.h><br> + +<p>string popen(string <I>cmd</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function runs the command cmd as in a shell and returns the +output. See your unix/C manual for details on popen. +<p> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=pow> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>pow</tt> - Raise a number to the power of another. +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float pow(float <I>n</I>, float <I>x</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return n raised to the power of x. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_exp.html>exp</a> and <a href=math_log.html>log</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=previous_object> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>previous_object</tt> - return the calling object +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>object previous_object();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns an object pointer to the object that called current function, +if any. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_call_function.html>call_function</a> and <a href=builtin_backtrace.html>backtrace</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=programp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>programp</tt> - is the argument an program? +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int programp(mixed <I>arg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns 1 if arg is a program, zero otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_program.html>program</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_intp.html>intp</a>, <a href=builtin_multisetp.html>multisetp</a>, <a href=builtin_arrayp.html>arrayp</a>, <a href=builtin_stringp.html>stringp</a>, <a href=builtin_objectp.html>objectp</a>, <a href=builtin_mappingp.html>mappingp</a>, <a href=builtin_floatp.html>floatp</a> and <a href=builtin_functionp.html>functionp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=putenv> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>putenv</tt> - put environment variable +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void putenv(string <I>varname</I>, string <I>value</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sets the environment variable 'varname' to 'value'. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_getenv.html>getenv</a> and <a href=files_exece.html>exece</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=query_host_name> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>query_host_name</tt> - return the name of the host we are running on +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string query_host_name();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the name of the machine the interpreter is +running on. This is the same thing that the command 'hostname' +prints. + +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=query_num_arg> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>query_num_arg</tt> - find out how many arguments were given +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int query_num_arg();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Query_num_arg returns the number of arguments given when this +function was called. This is only useful for varargs functions. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_call_function.html>call_function</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=random> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>random</tt> - return a random number +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int random(int <I>max</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns a random number in the range 0 - max-1. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_int.html>int</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_random_seed.html>random_seed</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=random_seed> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>random_seed</tt> - seed random generator +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void random_seed(int <I>seed</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sets the initial value for the random generator. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>Pike v1.0E-13 Running Hilfe v1.2 (Hubbe's Incremental Pike FrontEnd)<br> +> random_seed(17);<br> +Result: 0<br> +> random(1000);<br> +Result: 732<br> +> random(1000);<br> +Result: 178<br> +> random(1000);<br> +Result: 94<br> +> random_seed(17);<br> +Result: 0<br> +> random(1000);<br> +Result: 732<br> +> random(1000);<br> +Result: 178<br> +> random(1000);<br> +Result: 94<br> +><br> +</tt> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_int.html>int</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_random.html>random</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=read_bytes> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>read_bytes</tt> - read a number of bytes into a string from a file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <stdio.h><br> + +<p>string read_bytes(string <I>file</I>,int <I>start</I>,int <I>len</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Read len number of bytes from file file staring at byte start and +return it as a string. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_write_file.html>write_file</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=read_file> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>read_file</tt> - read a number of lines into a string from file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <stdio.h><br> + +<p>string read_file(string <I>file</I>, int <I>start</I>, int <I>len</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Read 'len' lines from the file 'file' after skipping 'start' lines +and return those lines as a string. If start and len are omitted +the whole file is read. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_read_bytes.html>read_bytes</a> and <a href=simulated_write_file.html>write_file</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=readline> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>readline</tt> - read a line from stdin +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string readline(string <I>prompt</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function writes the string 'prompt' and then waits until the +user has entered a line from the keyboard. If the readline library +was available when Pike was compiled the user will have history and +line edithing at his/her disposal when entering the line. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=index.html#file>file</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=regexp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>regexp</tt> - filter an array through a regexp +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>string *regexp(string *<I>arr</I>, string <I>reg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return those strings in arr that matches the regexp in reg. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_regexp.html>regexp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=remove_call_out> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>remove_call_out</tt> - remove a call out from the call out queue +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int remove_call_out(function <I>f</I>);<br> +or<br> +int remove_call_out(function <I>id</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function finds the first call to the function f in the call +out queue and removes it. The time left to that call out will be +returned. If no call out was found, zero_type(remove_call_out(f)) +will return 1. You can also give a call out id as argument. (as +returned by call_out) +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=call_out_call_out_info.html>call_out_info</a>, <a href=call_out_call_out.html>call_out</a> and <a href=call_out_find_call_out.html>find_call_out</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=replace> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>replace</tt> - generic replace function +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string replace(string <I>s</I>, string <I>from</I>, string <I>to</I>);<br> +or<br> +string replace(string <I>s</I>, string *<I>from</I>, string *<I>to</I>);<br> +or<br> +array replace(array <I>a</I>, mixed <I>from</I>, mixed <I>to</I>);<br> +or<br> +mapping replace(mapping <I>a</I>, mixed <I>from</I>, mixed <I>to</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function can do several kinds replacement operations, the +different syntaxes do different things as follow: +<p>string replace(string s, string from, string to); +<p><dl><dt><dd>When given strings as second and third argument, a copy of<br> +s with every occurance of 'from' return 'to' is returned.<br> +</dl> +<p>string replace(string s, string *from, string *to); +<p><dl><dt><dd>When given arrays of strings as second and third argument,<br> +every occurance of from[0] in s is replaced by to[0],<br> +from[1] is replaced by to[1] and so on...<br> +</dl> +<p><table border=0 cellpadding=0 cellspacing=0> +<tr valign=top><td> array replace(array a, mixed from, mixed to); </td><td> </td></tr> +<tr valign=top><td> mapping replace(mapping a, mixed from, mixed to); </td></tr> +</table> + +<p><dl><dt><dd>When the first argument is an array or mapping, the values in<br> +a are searched for values equal to from, which are replaced by<br> +to destructively.<br> +</dl> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a>, <a href=types_array.html>array</a> and <a href=types_mapping.html>mapping</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=replace_master> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>replace_master</tt> - replace the master object +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void replace_master(object <I>o</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function replaces the master object with the argument you specify. +This will let you control many aspects of how pike works, but beware that +master.pike may be required to fill certain functions, so it is probably +a good idea to have your master inherit the original master and only +re-define certain functions. +<!-- FIXME, tell how to inherit the master --> +</dl> +</a> + +<HR NEWPAGE> +<a name=reverse> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>reverse</tt> - reverse a string, array or int +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string reverse(string <I>s</I>);<br> +or<br> +array reverse(arary <I>a</I>);<br> +or<br> +int reverse(int <I>i</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function reverseses a string, char by char, an array, value +by value or an int, bit by bit and returns the result. Reversing +strings can be particularly useful for parsing difficult syntaxes +which require scanning backwards. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a>, <a href=types_array.html>array</a> and <a href=types_int.html>int</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=pike_sscanf.html>sscanf</a> +<p> +</dl> +</a> + + +<HR NEWPAGE> +<a name=rm> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>rm</tt> - remove file or directory +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int rm(string <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Remove a file or directory, return 0 if it fails. Nonzero otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_mkdir.html>mkdir</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=rows> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>rows</tt> - select a set of rows from an array +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>array rows(mixed data, mixed *index)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is exactly equivialent to: +<p>map_array(index,lambda(mixed x,mixed y) { return y[x]; },data) +<p>Except of course it is a lot shorter and faster. +That is, it indexes data on every index in the array index and +returns an array with the results. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_column.html>column</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=rusage> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>rusage</tt> - return resource usage +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int *rusage();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns an array of ints describing how much resources +the intepreter process has used so far. This array will have at least +29 elements, of which those values not available on this system will +be zero. The elements are as follows: +<p>0: user time +1: system time +2: maxrss +3: idrss +4: isrss +5: minflt +6: minor pagefaults +7: major pagefaults +8: swaps +9: block input op. +10: block output op. +11: messages sent +12: messages received +13: signals received +14: voluntary context switches +15: involuntary context switches +16: sysc +17: ioch +18: rtime +19: ttime +20: tftime +21: dftime +22: kftime +23: ltime +24: slptime +25: wtime +26: stoptime +27: brksize +28: stksize +<p>Don't ask me to explain these values, read your system manuals for +more information. (Note that all values may not be present though) +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_time.html>time</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=search> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>search</tt> - search for a value in a string or array +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int search(string <I>haystack</I>, string <I>needle</I>, [ int <I>start</I> ]);<br> +or<br> +int search(mixed *<I>haystack</I>, mixed <I>needle</I>, [ int <I>start</I> ]);<br> +or<br> +mixed search(mapping <I>haystack</I>, mixed <I>needle</I>, [ mixed <I>start</I> ]);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Search for needle in haystack. Return the position of needle in +haystack or -1 if not found. If the optional argument start is present +search is started at this position. Note that when haystack is a string +needle must be a string, and the first occurance of this string is +returned. However, when haystack is an array, needle is compared only +to one value at a time in haystack. +<p>When the haystack is a mapping, search tries to find the index +connected to the data needle. That is, it tries to lookup the mapping +backwards. If needle isn't present in the mapping, zero is returned, +and zero_type() will return 1 for this zero. +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +This function replaces strstr and member_array from Pike4. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a>, <a href=types_array.html>array</a> and <a href=types_mapping.html>mapping</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_indices.html>indices</a>, <a href=builtin_values.html>values</a> and <a href=builtin_zero_type.html>zero_type</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=search_array> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>search_array</tt> - search for something in an array +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <array.h><br> + +<p>int search_array(mixed *<I>arr</I>,function <I>fun</I>,mixed <I>arg</I>, ...);<br> +or<br> +int search_array(object *<I>arr</I>,string <I>fun</I>,mixed <I>arg</I>, ...);<br> +or<br> +int search_array(function *<I>arr</I>,-<I>1</I>,mixed <I>arg</I>, ...);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +search_array works like map_array, only it returns the index of the +first call that returned true instead or returning an array of the +returned values. If no call returns true, -1 is returned. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_sum_arrays.html>sum_arrays</a>, <a href=simulated_filter_array.html>filter_array</a> and <a href=simulated_member_array.html>member_array</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=signal> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>signal</tt> - trap signals +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void signal(int <I>sig</I>, function(int:void) <I>callback</I>);<br> +or<br> +void signal(int <I>sig</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function allows you to trap a signal and have a function called +when the process receives a signal. Although it IS possible to trap +SIGBUS, SIGSEGV etc. I advice you not to. Pike should not receive any +such signals and if it does it is because of bugs in the Pike +interperter. And all bugs should be reported, no matter how trifle. +<p>The callback will receive the signal number as the only argument. +See the document for the function 'kill' for a list of signals. +<p>If no second argument is given, the signal handler for that signal +is restored to the default handler. +<p>If the second argument is zero, the signal will be completely ignored. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_kill.html>kill</a>, <a href=builtin_signame.html>signame</a> and <a href=builtin_signum.html>signum</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=signame> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>signame</tt> - get the name of a signal +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string signame(int <I>sig</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return a string describing the signal. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>> signame(9);<br> +Result: SIGKILL<br> +</tt> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_kill.html>kill</a>, <a href=builtin_signum.html>signum</a> and <a href=builtin_signal.html>signal</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=signum> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>signum</tt> - get a signal number given a desctiptive string +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int signum(string <I>sig</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is the opposite of signame. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>> signum("SIGKILL");<br> +Result: 9<br> +</tt> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_signame.html>signame</a>, <a href=builtin_kill.html>kill</a> and <a href=builtin_signal.html>signal</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=sin> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>sin</tt> - Trigonometrical sine +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float sin(float <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the sinus value for f. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_asin.html>asin</a> and <a href=math_cos.html>cos</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=sizeof> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>sizeof</tt> - return the size of an array, string, multiset or mapping +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int sizeof(string|multiset|mapping|array|object <I>a</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the number of indexes available in the argument +given to it. It replaces older functions like strlen, m_sizeof and +size. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a>, <a href=types_multiset.html>multiset</a>, <a href=types_mapping.html>mapping</a> and <a href=types_array.html>array</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=sleep> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>sleep</tt> - let interpreter doze off for a while +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void sleep(int <I>s</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function makes the program stop for s seconds. Only signal +handlers can interrupt the sleep. Other callbacks are not called +during sleep. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_signal.html>signal</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=sort> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>sort</tt> - sort an array destructively +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed *sort(array(mixed) <I>index</I>, array(mixed) ... <I>data</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sorts the array 'index' destructively. That means +that the array itself is changed and returned, no copy is created. +If extra arguments are given, they are supposed to be arrays of the +same size. Each of these arrays will be modified in the same way as +'index'. Ie. if index 3 is moved to position 0 in 'index' index 3 +will be moved to position 0 in all the other arrays as well. +<p>Sort can sort strings, integers and floats in ascending order. +Arrays will be sorted first on the first element of each array. +<p>Sort returns it's first argument. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_reverse.html>reverse</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=sort_array> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>sort_array</tt> - sort an array +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <array.h><br> + +<p>mixed *sort_array(mixed *<I>arr</I>,function <I>fun</I>,mixed ... <I>args</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function sorts an array after a compare-function 'fun' +which takes two arguments and should return 1 if the first argument +is larger then the second. The rest of the arguments 'args' will be +sent as 3rd, 4th etc. argument to fun. If fun is omitted, `< is unsed +instead. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_map_array.html>map_array</a> and <a href=simulated_filter_array.html>filter_array</a> +<p> +</dl> +</a> + + +<HR NEWPAGE> +<a name=spawn> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>spawn</tt> - spawn a process +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <process.h><br> + +<p>int spawn(string <I>cmd</I>);<br> +or<br> +int spawn(string <I>cmd</I>, object <I>stdin</I>);<br> +or<br> +int spawn(string <I>cmd</I>, object <I>stdin</I>, object <I>stdout</I>);<br> +or<br> +int spawn(string <I>cmd</I>, object <I>stdin</I>, object <I>stdout</I>, object <I>stderr</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function spawns a process but does not wait for it to finish. +Optionally, clones of /precompiled/file can be sent to it to +specify where stdin, stdout and stderr of the spawned processes +should go. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_popen.html>popen</a>, <a href=files_fork.html>fork</a>, <a href=simulated_exec.html>exec</a>, <a href=files_file.html#pipe>file->pipe</a> and <a href=files_file.html#dup2>file->dup2</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=sprintf> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>sprintf</tt> - print the result from sprintf +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string sprintf(string <I>format</I>,mixed <I>arg</I>,....);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +The format string is a string containing a description of how to +output the data in the rest of the arguments. This string should +generally speaking have one %<modifiers><operator> (examples: +%s, %0d, %-=20s) for each of the rest arguments. +<p>Modifiers: +<p><table border=0 cellpadding=0 cellspacing=0> +<tr valign=top><td> 0 </td><td> Zero pad numbers (implies right justification) </td></tr> +<tr valign=top><td> ! </td><td> Toggle truncation </td></tr> +<tr valign=top><td> ' ' (space) </td><td> pad positive integers with a space </td></tr> +<tr valign=top><td> + </td><td> pad positive integers with a plus sign </td></tr> +<tr valign=top><td> - </td><td> left adjusted within field size (default is right) </td></tr> +<tr valign=top><td> | </td><td> centered within field size </td></tr> +<tr valign=top><td> = </td><td> column mode if strings are greater than field size </td></tr> +<tr valign=top><td> / </td><td> Rough linebreak (break at exactly fieldsize instead of between words) </td></tr> +<tr valign=top><td> # </td><td> table mode, print a list of '\n' separated word (top-to-bottom order) </td></tr> +<tr valign=top><td> $ </td><td> Inverse table mode (left-to-right order) </td></tr> +<tr valign=top><td> n </td><td> (where n is a number or *) a number specifies field size </td></tr> +<tr valign=top><td> .n </td><td> set precision </td></tr> +<tr valign=top><td> :n </td><td> set field size & precision </td></tr> +<tr valign=top><td> ;n </td><td> Set column width </td></tr> +<tr valign=top><td> * </td><td> if n is a * then next argument is used for precision/field size </td></tr> +<tr valign=top><td> 'X' </td><td> Set a pad string. ' cannot be a part of the pad_string (yet) </td></tr> +<tr valign=top><td> ~ </td><td> Get pad string from argument list. </td></tr> +<tr valign=top><td> < </td><td> Use same arg again </td></tr> +<tr valign=top><td> ^ </td><td> repeat this on every line produced </td></tr> +<tr valign=top><td> @ </td><td> do this format for each entry in argument array </td></tr> +<tr valign=top><td> > </td><td> Put the string at the bottom end of column instead of top </td></tr> +<tr valign=top><td> _ </td><td> Set width to the length of data </td></tr> +</table> + +<p>Operators: +<p><table border=0 cellpadding=0 cellspacing=0> +<tr valign=top><td> %% </td><td> percent </td></tr> +<tr valign=top><td> %d </td><td> signed decimal int </td></tr> +<tr valign=top><td> %u </td><td> unsigned decimal int (doesn't really exist in Pike) </td></tr> +<tr valign=top><td> %o </td><td> unsigned octal int </td></tr> +<tr valign=top><td> %x </td><td> lowercase unsigned hexadecimal int </td></tr> +<tr valign=top><td> %X </td><td> uppercase unsigned hexadecimal int </td></tr> +<tr valign=top><td> %c </td><td> char (or short with %2c, %3c gives 3 bytes etc.) </td></tr> +<tr valign=top><td> %f </td><td> float </td></tr> +<tr valign=top><td> %g </td><td> heruistically chosen representation of float </td></tr> +<tr valign=top><td> %e </td><td> exponential notation float </td></tr> +<tr valign=top><td> %s </td><td> string </td></tr> +<tr valign=top><td> %O </td><td> any type (debug style) </td></tr> +<tr valign=top><td> %n </td><td> nop </td></tr> +<tr valign=top><td> %t </td><td> type of argument </td></tr> +<tr valign=top><td> %<modifiers>{format%} </td><td> do a format for every index in an array. </td></tr> +</table> + +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLES</font></b><dd> +<tt>Pike v0.1 Running Hilfe v1.2 (Incremental Pike Frontend)<br> +> int screen_width=70;<br> +Result: 70<br> +> mixed sample;<br> +> write(sprintf("fish: %c\n", 65));<br> +fish: A<br> +Result: 0<br> +> write(sprintf("Hello green friends\n"));<br> +Hello green friends<br> +Result: 0<br> +> write(sprintf("num: %d\n", 10));<br> +num: 10<br> +Result: 0<br> +> write(sprintf("num: %+10d\n", 10));<br> +num: +10<br> +Result: 0<br> +> write(sprintf("num: %010d\n", 5*2));<br> +num: 0000000010<br> +Result: 0<br> +> write(sprintf("num: %|10d\n", 20/2));<br> +num: 10 <br> +Result: 0<br> +> write(sprintf("%|*s\n",screen_width,"THE NOT END"));<br> +<dl><dt><dd>THE NOT END <br> +</dl>Result: 0<br> +> write(sprintf("%|=*s\n",screen_width, "fun with penguins\n"));<br> +<dl><dt><dd>fun with penguins <br> +</dl>Result: 0<br> +> write(sprintf("%-=*O\n",screen_width,({ "fish", 9, "gumbies", 2 })));<br> +({ /* 4 elements */ <br> +<dl><dt><dd>"fish", <br> +9, <br> +"gumbies", <br> +2 <br> +</dl>}) <br> +Result: 0<br> +> write(sprintf("%-=*s\n", screen_width,<br> +<dl><dt><dd>"This will wordwrap the specified string within the "+<br> +"specified field size, this is useful say, if you let "+<br> +"users specify their screen size, then the room "+<br> +"descriptions will automagically word-wrap as appropriate.\n"+<br> +"slosh-n's will of course force a new-line when needed.\n"));<br> +</dl>This will wordwrap the specified string within the specified field <br> +size, this is useful say, if you let users specify their screen size, <br> +then the room descriptions will automagically word-wrap as <br> +appropriate. <br> +slosh-n's will of course force a new-line when needed. <br> +Result: 0<br> +> write(sprintf("%-=*s %-=*s\n", screen_width/2,<br> +<dl><dt><dd>"Two columns next to each other (any number of columns will "+<br> +"of course work) independantly word-wrapped, can be useful.",<br> +screen_width/2-1,<br> +"The - is to specify justification, this is in addherence "+<br> +"to std sprintf which defaults to right-justification, "+<br> +"this version also supports centre and right justification."));<br> +</dl>Two columns next to each other (any The - is to specify justification,<br> +number of columns will of course this is in addherence to std <br> +work) independantly word-wrapped, sprintf which defaults to <br> +can be useful. right-justification, this version <br> +<dl><dt><dd>also supports centre and right <br> +justification. <br> +</dl>Result: 0<br> +> write(sprintf("%-$*s\n", screen_width,<br> +<dl><dt><dd>"Given a\nlist of\nslosh-n\nseparated\n'words',\nthis option\n"+<br> +"creates a\ntable out\nof them\nthe number of\ncolumns\n"+<br> +"be forced\nby specifying a\npresision.\nThe most obvious\n"+<br> +"use is for\nformatted\nls output."));<br> +</dl>Given a list of slosh-n <br> +separated 'words', this option <br> +creates a table out of them <br> +the number of columns be forced <br> +by specifying a presision. The most obvious <br> +use is for formatted ls output. <br> +Result: 0<br> +> write(sprintf("%-#*s\n", screen_width,<br> +<dl><dt><dd>"Given a\nlist of\nslosh-n\nseparated\n'words',\nthis option\n"+<br> +"creates a\ntable out\nof them\nthe number of\ncolumns\n"+<br> +"be forced\nby specifying a\npresision.\nThe most obvious\n"+<br> +"use is for\nformatted\nls output."));<br> +</dl>Given a creates a by specifying a <br> +list of table out presision. <br> +slosh-n of them The most obvious <br> +separated the number of use is for <br> +'words', columns formatted <br> +this option be forced ls output. <br> +Result: 0<br> +> sample = ({ "first column: bing", "second column: womble" });<br> +Result: ({ /* 2 elements */<br> +<dl><dt><dd>"first column: bing",<br> +"second column: womble"<br> +</dl>})<br> +> write(sprintf("%-=*s\n%-=@*s\n", screen_width,<br> +<dl><dt><dd>"Another bizarre option is the @ operator, it applies the "+<br> +"format string it is in to each element of the array:",<br> +screen_width/sizeof(sample),<br> +sample));<br> +</dl>Another bizarre option is the @ operator, it applies the format string<br> +it is in to each element of the array: <br> +first column: bing second column: womble <br> +Result: 0<br> +> write(sprintf("Better use these instead: %{gurksallad: %s\n%}\n",<br> +<dl><dt><dd>sample));<br> +</dl>Better use these instead: gurksallad: first column: bing<br> +gurksallad: second column: womble<br> +<br> +Result: 0<br> +> write(sprintf("Of course all the simple printf options "+<br> +<dl><dt><dd>"are supported:\n %s: %d %x %o %c\n",<br> +"65 as decimal, hex, octal and a char",<br> +65, 65, 65, 65));<br> +</dl>Of course all the simple printf options are supported:<br> +<dl><dt><dd>65 as decimal, hex, octal and a char: 65 41 101 A<br> +</dl>Result: 0<br> +> write(sprintf("%|*s\n",screen_width, "THE END"));<br> +<dl><dt><dd>THE END <br> +</dl>Result: 0<br> +> quit<br> +Exiting.<br> +</tt> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=pike_sscanf.html>sscanf</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=sqrt> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>sqrt</tt> - Square root +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float sqrt(float <I>f</I>);<br> +or<br> +int sqrt(int <I>i</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the square root of f, or in the second case, the square root +truncated to the closest lower integer. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> and <a href=types_int.html>int</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_pow.html>pow</a>, <a href=math_log.html>log</a>, <a href=math_exp.html>exp</a> and <a href=math_floor.html>floor</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=stderr> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>stderr</tt> - Standard error stream +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>#include <stdio.h><br> + +<p>stderr->write("foo")<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Stderr is a clone of /precompiled/file connected to the standard +error stream. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_file.html>/precompiled/file</a> and <a href=files_werror.html>werror</a> +<p> +</dl> +</a> + + +<HR NEWPAGE> +<a name=stdin> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>stdin</tt> - Standard input +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>#include <stdio.h><br> + +<p>stdin->gets()<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Stdin is a clone of /precompiled/FILE connected to the standard input. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=precompiled_FILE.html>/precompiled/FILE</a> +<p> +</dl> + +<HR NEWPAGE> +<a name=stdout> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>stdout</tt> - Standard output +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>#include <stdio.h><br> + +<p>stdout->gets()<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Stdout is a clone of /precompiled/file connected to the standard output. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_file.html>/precompiled/file</a> and <a href=simulated_write.html>write</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=strerror> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>strerror</tt> - return a string describing an error +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string strerror(int <I>errno</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns a description of an error code. The error +code is usually obtained from the file->errno() call. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +This function may not be available on all platforms. +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=stringp> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>stringp</tt> - is the argument an string? +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int stringp(mixed <I>arg</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns 1 if arg is a string, zero otherwise. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_intp.html>intp</a>, <a href=builtin_multisetp.html>multisetp</a>, <a href=builtin_arrayp.html>arrayp</a>, <a href=builtin_programp.html>programp</a>, <a href=builtin_objectp.html>objectp</a>, <a href=builtin_mappingp.html>mappingp</a>, <a href=builtin_floatp.html>floatp</a> and <a href=builtin_functionp.html>functionp</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=strlen> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>strlen</tt> - Return the length of a string +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>int strlen(string <I>s</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function is equal to sizeof. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_sizeof.html>sizeof</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=strmult> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>strmult</tt> - multiply strings +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <string.h><br> + +<p>string strmult(string <I>s</I>, int <I>num</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function multplies 's' by 'num'. The return value is the same +as appending 's' to an empty string 'num' times. +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=strstr> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>strstr</tt> - find a string inside a string +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>int strstr(string <I>str1</I>,string <I>str2</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the position of str2 in str1, if str2 can't be found in str1 +-1 is returned. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=pike_sscanf.html>sscanf</a> and <a href=simulated_explode.html>explode</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=sum> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>sum</tt> - add values together +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>int sum(int ... <I>i</I>);<br> +or<br> +float sum(float ... <I>f</I>);<br> +or<br> +string sum(string|float|int ... <I>p</I>);<br> +or<br> +array sum(array ... <I>a</I>);<br> +or<br> +mapping sum(mapping ... <I>m</I>);<br> +or<br> +list sum(multiset ... <I>l</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function does exactly the same thing as adding all the arguments +together with +. It's just here so you can get a function-pointer to +the summation operator. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_int.html>int</a>, <a href=types_float.html>float</a>, <a href=types_string.html>string</a>, <a href=types_array.html>array</a>, <a href=types_mapping.html>mapping</a> and <a href=types_multiset.html>multiset</a> +<p> +</dl> +d +</a> + +<HR NEWPAGE> +<a name=sum_arrays> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>sum_arrays</tt> - map any number of arrays over a function. +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <array.h><br> + +<p>mixed *sum_arrays(function <I>fun</I>,mixed *<I>arr1</I>,...);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Works like this: +<p>mixed *sum_arrays(function fun,mixed *arr1,...)<br> +{<br> +<dl><dt><dd>int e;<br> +mixed *res=allocate(sizeof(arr1));<br> +for(e=0;e<sizeof(arr1);e++)<br> +{<br> +<dl><dt><dd>res[e]=fun(arr1[e],arr2[e],...);<br> +</dl>}<br> +return res;<br> +</dl>}<br> + +<p>Simple ehh? +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_map_array.html>map_array</a>, <a href=simulated_filter_array.html>filter_array</a> and <a href=simulated_search_array.html>search_array</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=system> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>system</tt> - run an external program +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <process.h><br> + +<p>void system(string <I>cmd</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function runs the external program cmd and waits until it +is finished. Standard /bin/sh completions/redirectoins/etc. can +be used. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_popen.html>popen</a>, <a href=simulated_exec.html>exec</a> and <a href=simulated_spawn.html>spawn</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=tan> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>tan</tt> - Trigonometrical tangent +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>float tan(float <I>f</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return the tangent value for f. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_float.html>float</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=math_atan.html>atan</a>, <a href=math_sin.html>sin</a> and <a href=math_cos.html>cos</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=this_function> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>this_function</tt> - return a functionpointer to the current function +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <simulate.h><br> + +<p>function this_function();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Returns a functionpointer to the current function, useful for +making recursive lambda-functions. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_function.html>function</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_get_function.html>get_function</a>, <a href=builtin_function_name.html>function_name</a>, <a href=builtin_function_object.html>function_object</a> and <a href=builtin_backtrace.html>backtrace</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=this_object> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>this_object</tt> - return the object we are evaluating in currently +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object this_object();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the object we are curently evaluating in. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_object.html>object</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=this_thread> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>this_thread</tt> - return thread id +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object thread_id();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the object that identifies this thread. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_thread_create.html>thread_create</a> +<p> +</dl> + +</a> + +<HR NEWPAGE> +<a name=thread_create> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>thread_create</tt> - create a thread +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>object thread_create(function <I>f</I>, mixed ... <I>args</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function creates a new thread which will run simultaneously +to the rest of the program. The new thread will call the function +f with the arguments args. When f returns the thread will cease +to exist. All Pike functions are 'thread safe' meanting that running +a function at the same time from different threads will not corrupt +any internal data in the Pike process. The returned value will be +the same as the return value of this_thread() for the new thread. +<p> +<dt><b> <font size=+1>N</font><font size=-1>OTA</font> <font size=+1>B</font><font size=-1>ENE</font></b><dd> +This function is only available on systems with POSIX threads support. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=precompiled_mutex.html>/precompiled/mutex</a>, <a href=precompiled_condition.html>/precompiled/condition</a> and <a href=builtin_this_thread.html>this_thread</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=throw> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>throw</tt> - throw a value to catch or global error handling +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void throw(mixed <I>value</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function throws a value to a waiting catch. If no catch is +waiting global error handling will send the value to handle_error +in the master object. If you throw an array with where the first +index contains an error message and the second index is a backtrace, +(the output from backtrace() that is) then it will be treated exactly +like a real error by overlying functions. +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=pike_control_structures_catch.html>catch</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=time> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>time</tt> - return the current time +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int time();<br> +or<br> +int time(1);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns the number of secons since 1 Jan 1970. +The function ctime() converts this integer to a readable string. +<p>The second syntax does not call the system call time() as often, +but is only updated in the backed. (when pike code isn't running) +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_time.html>time</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=trace> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>trace</tt> - change debug trace level +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int trace(int <I>t</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function affects the debug trace level. (also set by the -t +command line option) The old level is returned. Trace level 1 or +higher means that calls to pike functions are printed to stderr, +level 2 or higer means calls to builtin functions are printed, 3 +means every opcode interpreted is printed, 4 means arguments to +these opcodes are printed as well. See the command lines options +for more information +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=typeof> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>typeof</tt> - check return type of expression +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>typeof ( expression )<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This is a not really a function even if it looks like it, it returns +a human readable (almost) representation of the type that the +expression would return without actually evaluating it. +The representation is in the form of a string. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>> typeof(`sizeof);<br> +Result: function(object | mapping | array | multiset | string : int)<br> +> typeof(sizeof(({})));<br> +Result: int<br> +> <br> +</tt> +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#pike>pike</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=ualarm> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>ualarm</tt> - set an alarm clock for delivery of a signal +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int ualarm(int <I>useconds</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +ualarm arranges for a SIGALRM signal to be delivered to the +process in useconds micro seconds. +<p>If useconds is zero, no new alarm is scheduled. +<p>In any event any previously set alarm is cancelled. +<p> +<dt><b> <font size=+1>R</font><font size=-1>ETURN</font> <font size=+1>V</font><font size=-1>ALUE</font></b><dd> +ualarm returns the number of microseconds seconds remaining<br> +<dl><dt><dd>until any previously scheduled alarm was due to be delivered, or<br> +</dl>zero if there was no previously scheduled alarm.<br> + +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_signal.html>signal</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=uniq> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>uniq</tt> - return one of each element +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <array.h><br> + +<p>array uniq(array <I>a</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns an copy of the array a with all duplicate +values removed. The order of the values in the result is undefined. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_array.html>array</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=upper_case> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>upper_case</tt> - convert a string to upper case +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string upper_case(string <I>s</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Return a copy of the string s with all lower case character converted +to upper case character. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_string.html>string</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_lower_case.html>lower_case</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=values> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>values</tt> - return an array of all possible values from indexing +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>mixed *values(string|multiset|mapping|array|object <I>foo</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Values return an array of all values you can get when indexing the +value foo. For strings, an array of int with the ascii values of the +characters in the string is returned. For a multiset, an array filled with +ones is return. For mappings, objects and arrays, the returned array +may contain any kind of value. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_mapping.html>mapping</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=builtin_indices.html>indices</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=version> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>version</tt> - return version info +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>string version();<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +This function returns a brief information about the Pike version. +<p> +<dt><b> <font size=+1>E</font><font size=-1>XAMPLE</font></b><dd> +<tt>> version();<br> +Result: Pike v0.3<br> +<br> +</tt> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=werror> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>werror</tt> - write to stderr +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>void werror(string <I>s</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Writes a message to stderr. Stderr is normally the console, even if +the process output has been redirected to a file or pipe. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=write> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>write</tt> - write text to stdout +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int write(string <I>text</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Added by the master, it directly calls write in a clone of +/precompiled/file +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=files_werror.html>werror</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=write_file> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>write_file</tt> - append a string to a file +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>#include <stdio.h><br> + +<p>int write_file(string file, string str)<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +Append the string str onto the file file. Returns number of bytes written. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=index.html#file>file</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=simulated_read_bytes.html>read_bytes</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<a name=zero_type> +<dl> +<dt><b> <font size=+1>N</font><font size=-1>AME</font></b><dd> +<tt>zero_type</tt> - return the type of zero +<p> +<dt><b> <font size=+1>S</font><font size=-1>YNTAX</font></b><dd> +<tt>int zero_type(mixed <I>a</I>);<br> +</tt> +<p> +<dt><b> <font size=+1>D</font><font size=-1>ESCRIPTION</font></b><dd> +There are many types of zeros out there, or at least there are two. +One is returned by normal functions, and one returned by mapping +lookups and find_call_out() when what you looked for wasn't there. +The only way to separate these two kinds of zeros is zero_type. +When doing a find_call_out or mapping lookup, zero_type on this value +will return 1 if there was no such thing present in the mappping, or +no such call_out could be found. If the argument to zero type is a +destructed object or a function in a destructed object, 2 will be +returned. Otherwize zero_type will return zero. +<p>If the argument is not an int, zero will be returned. +<p> +<dt><b> <font size=+1>K</font><font size=-1>EYWORDS</font></b><dd> +<a href=types_int.html>int</a> and <a href=types_mapping.html>mapping</a> +<p> +<dt><b> <font size=+1>S</font><font size=-1>EE</font> <font size=+1>A</font><font size=-1>LSO</font></b><dd> +<a href=call_out_find_call_out.html>find_call_out</a> +<p> +</dl> +</a> + +<HR NEWPAGE> +<HR NEWPAGE> +<HR NEWPAGE> +<HR NEWPAGE> +<HR NEWPAGE> +<!-- Find me! --> +<HR NEWPAGE> +<HR NEWPAGE> +<HR NEWPAGE> +<HR NEWPAGE> +<H1>XXX. Things to describe somewhere</H1> +<ul> + <li>garbage collection + <li>int ... ars + <li>how to write types + <li>data storage (local vs. global variables) + <li>exception handling (catch, throw) + <li>lambda + <li>gauge + <li>trace + <li>sscanf is not a function + <li>typeof + <li>pike command line + <li>hilfe + <li>{encode,decode}_value + <li>replace_master + <li>overloading of sizeof, indices, values + <li>mktime + <li>socket->query_address() + <li> scope for class {} +</ul> +<HR NEWPAGE> +<HR NEWPAGE> +<HR NEWPAGE> + +<H1>Pike internals - how to extend pike</H1> +<ul> + <li>Overview of the pike source + <li>The master object + <li>The file structure of a module + <li>Data types from the inside + <li>Writing portable modules: autoconf + <li>Other useful functions +</ul> + +<H1> Appendixes </H1> +<h2> Appendix A: Terms and jargon</h2> +<dl> + <dt> ASCII <dd> <!-- FIXME --> + <dt> UNIX <dd> A group of operating systems. Some noteworthy unixes are: Solaris, Linux, HP-UX, Digital Unix, SunOs, BSD and Unixware. + <dt> clone <dd> To create an object from a program. Or to use C++ jargon: to instanciate a class. + <dt> command line <dd> The line you write to execute a program + <dt> command line option <dd> The words after the program name on the <i>command line</i>. + <dt> constant <dd> 1) A value written directly in the code, such as <tt>1</tt> or <tt>"foo"</tt>. 2) A value defined with add_constant. + <dt> identifier <dd> The name of a variable, function, class or constant. + <dt> interpreter <dd> An interpreter <i>interprets </i> byte-code instruction by instruction. In this context 'the interpreter' is usually the Pike binary. + <dt> iteration <dd> Iteration is when the program is executing a loop. Each time the loop is called is also called one iteration. + <dt> object <dd> An object is what you get if you call a program. Objects contain variables and a reference to the program from which they were cloned. Same as 'instance' in C++. + <dt> program <dd> 1) An executable file 2) A builtin Pike data type. Programs are almost the same as classes in C++ and contain the actual compiled code. + <dt> recursion <dd> Recursion is an alternative to iteration. Recursion occurs when a function calls itself. + <dt> stderr <dd> Standard error. The error channel. This is where errors are supposed to be written. It is usually the screen, but can be redirected to a file or another program. See the manual page for sh(1) for more details. + <dt> stdin <dd> Standard input. Usually the keyboard, but can also be from a file or another program. See the manual page for sh(1) for more details. + <dt> stdout <dd> Standard output. This is usually the screen but can be redirected to a file or another program. See the manual page for sh(1) for more details. +</dl> +<HR NEWPAGE> +<h2> Appendix B: Register program </h2> +Here is a complete listing of the example program from +chapter 2. + +<pre> +#!/usr/local/bin/pike + +mapping records(string:aray(string)) = ([ + "Star Wars Trilogy" : ({ + "Fox Fanfare", + "Main Title", + "Princess leia's Theme", + "Here They Come", + "The Asteriod Field", + "Yoda's Theme", + "The Imperial March", + "Parade of th Ewoks", + "Luke and Leia", + "Fight with Tie Fighters", + "Jabba the Hut", + "Darth Vader's Death", + "The Forest Battle", + "Finale", + }) +]); + +void list_records() +{ + int i; + string *record_names=sort(indices(records)); + + write("Records:\n"); + for(i=0;i<sizeof(record_names);i++) + write(sprintf("%3d: %s\n", i+1, record_names[i])); +} + +void show_record(int num) +{ + int i; + string *record_names=sort(indices(records)); + string name=record_names[num-1]; + string songs=records[name]; + + write(sprintf("Record %d, %s\n",num,name)); + for(i=0;i<sizeof(songs);i++) + write(sprintf("%3d: %s\n", i+1, songs[i])); +} + +void add_record() +{ + string record_name=readline("Record name: "); + records[record_name]=({}); + write("Input song names, one per line. End with '.' on it's own line.\n"); + while(1) + { + string song; + song=readline(sprintf("Song %2d: ",sizeof(records[record_name])+1)); + if(song==".") return; + records[record_name]+=({song}); + } +} + +void save(string file) +{ + string name, song; + object o; + o=File(); + + if(!o->open(file,"wct")) + { + write("Failed to open file.\n"); + return; + } + + foreach(indices(records),name) + { + o->write("Record: "+name+"\n"); + foreach(records[name],song) + o->write("Song: "+song+"\n"); + } + + o->close(); +} + +void load(string file) +{ + object o; + string name="ERROR"; + string file_contents,line; + + o=File(); + if(!o->open(file,"r")) + { + write("Failed to open file.\n"); + return; + } + + file_contents=o->read(); + o->close(); + + records=([]); + + foreach(file_contents/"\n",line) + { + string cmd, arg; + if(sscanf(line,"%s: %s",cmd,arg)) + { + switch(lower_case(cmd)) + { + case "record": + name=arg; + records[name]=({}); + break; + + case "song": + records[name]+=({arg}); + break; + } + } + } +} + +void delete_record(int num) +{ + string *record_names=sort(indices(records)); + string name=record_names[num-1]; + + m_delete(records,name); +} + +void find_song(string title) +{ + string name, song; + int hits; + + title=lower_case(title); + + foreach(indices(records),name) + { + foreach(records[name],song) + { + if(search(lower_case(song), title) != -1) + { + write(name+"; "+song+"\n"); + hits++; + } + } + } + + if(!hits) write("Not found.\n"); +} + +int main(int argc, string * argv) +{ + string cmd; + while(cmd=readline("Command: ")) + { + string args; + sscanf(cmd,"%s %s",cmd,args); + + switch(cmd) + { + case "list": + if((int)args) + { + show_record((int)args); + }else{ + list_records(); + } + break; + + case "quit": + exit(0); + + case "add": + add_record(); + break; + + case "save": + save(args); + break; + + case "load": + load(args); + break; + + case "delete": + delete_record((int)args); + break; + + case "search": + find_song(args); + break; + } + } +} +</pre> +<HR NEWPAGE> +<h2> Appendix C: Reserverd words </h2> + +These are words that have special meaning in Pike and can not be used +as variable or function names. +<p> + array break case catch continue default do else float for foreach + function gauge if inherit inline int lambda mapping mixed multiset nomask + object predef private program protected public return sscanf static string + switch typeof varargs void while + +<HR NEWPAGE> +<h2> Appendix D: BNF for Pike </h2> +program: + +<HR NEWPAGE> +<h2> Appendix E: How to install Pike</h2> +To install pike, you need a C compiler, a couple of Mb of disk space, +the source for Pike, and a bit of patientce. The latest version of Pike is +always available from <a href=http://pike.infovav.se>the Pike home page</a>. +lists of mirror sites and binary releases should also be available there. +Pike should compile and install nicely on almost any UNIX platform. It has +been tested on the following: +<ul> +<li> Solaris 2.4, 2.5 +<li> Sunos 4.1.1, 4.1.3 +<li> Linux Red Hat 3, Red Hat 4, Slackware 3.0, Slackware 96 +<li> HP-UX 9, 10 +<li> AIX 4 +<li> IRIX +<li> SCO UNIX +<li> Ultrix +<li> Digital Unix (OSF/1) +</ul> + +After obtaining the Pike source you need to unpack it. To unpack Pike you +need gzip, which is available from any GNU mirror site. You also need tar, +which is a part of UNIX. If you got Pike-v0.3.tar.gz, simply unpack it by +typing: +<pre> + $ gunzip -d Pike-v0.3.tar.gz + $ tar xvf Pike-v0.3.tar +</pre> + +Now you have a directory called Pike-v0.3. Please read the README file +in the new directory since newer version can contain information not +available at the time this book was written. +<p> +Now, to compile Pike, the following three commands should be enough. +<pre> + $ cd Pike-v0.3/src + $ ./configure --prefix=/dir/to/install/pike + $ make +</pre> +They will (in order) change directory to the source directory. Configure will +then find out what features are available on your system and construct +makefiles. You will see a lot of output after you run configure. Do not +worry, that is normal. It is usually not a good idea to install pike anywhere +but in /usr/local (the default) since Pike scripts written by other people +will usually assume that's where Pike is. However, if you do not have write +acceess to /usr/local you will have to install Pike somewhere else on your +system. +<p> +After that <tt>make</tt> will actually compile the program. After compilation +it is a good idea to do <tt>make verify</tt> to make sure that Pike is +100% compatible with your system. Make verify will take a while to run +and use a lot of cpu, but it is worth it to see that your compilation was +successful. After doing that you should run <tt>make install</tt> to install +the pike binaries, libraries and include files in the directory you selected +earlier. +<p> +You are now ready to use Pike. +<HR NEWPAGE> +<h1> Index </h1> +<table cellpadding=0> +<tr><td>true</td></tr> +<tr><td>false</td></tr> +</table> +