From 579b59728392bf87f32ae6c50e95a3d46ac1f5f5 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 25 Mar 1998 11:26:49 +0000 Subject: [PATCH] Initial revision --- bugs/BUG0052.PP | 20 + bugs/BUG0083.PP | 8 + bugs/bug0001.pp | 8 + bugs/bug0002.pp | 83 ++ bugs/bug0003.pp | 18 + bugs/bug0004.pp | 12 + bugs/bug0005.pp | 8 + bugs/bug00051.pp | 6 + bugs/bug0006.pp | 14 + bugs/bug00061.pp | 8 + bugs/bug0007.pp | 10 + bugs/bug0008.pp | 6 + bugs/bug0009.pp | 16 + bugs/bug0010.pp | 6 + bugs/bug0011.pp | 13 + bugs/bug0012.pp | 10 + bugs/bug0013.pp | 9 + bugs/bug0014.pp | 22 + bugs/bug00141.pp | 44 + bugs/bug0015.pp | 20 + bugs/bug0016.pp | 193 +++ bugs/bug0017.pp | 27 + bugs/bug0018.pp | 11 + bugs/bug0019.pp | 12 + bugs/bug0020.pp | 26 + bugs/bug0021.pp | 39 + bugs/bug0022.pp | 29 + bugs/bug0023.pp | 47 + bugs/bug0024.pp | 24 + bugs/bug0025.pp | 15 + bugs/bug0026.pp | 22 + bugs/bug0027.pp | 5 + bugs/bug0028.pp | 10 + bugs/bug0029.pp | 10 + bugs/bug0030.pp | 6 + bugs/bug0031.pp | 8 + bugs/bug0032.pp | 6 + bugs/bug0033.pp | 13 + bugs/bug0034.pp | 12 + bugs/bug0035.pp | 13 + bugs/bug0036.pp | 9 + bugs/bug0037.pp | 17 + bugs/bug0038.pp | 5 + bugs/bug0039.pp | 10 + bugs/bug0040.pp | 26 + bugs/bug0041.pp | 8 + bugs/bug0042.pp | 10 + bugs/bug0043.pp | 32 + bugs/bug0044.pp | 16 + bugs/bug0045.pp | 26 + bugs/bug0046.pp | 43 + bugs/bug0047.pp | 13 + bugs/bug0048.pp | 26 + bugs/bug0049.pp | 6 + bugs/bug0050.pp | 9 + bugs/bug0051.pp | 31 + bugs/bug0053.pp | 15 + bugs/bug0054.pp | 6 + bugs/bug0055.pp | 15 + bugs/bug0056.pp | 14 + bugs/bug0057.pp | 18 + bugs/bug0058.pp | 9 + bugs/bug0059.pp | 9 + bugs/bug0060.pp | 21 + bugs/bug0061.pp | 3 + bugs/bug0062.pp | 9 + bugs/bug0063.pp | 13 + bugs/bug0064.pp | 15 + bugs/bug0065.pp | 10 + bugs/bug0066.pp | 10 + bugs/bug0067.pp | 18 + bugs/bug0067b.pp | 27 + bugs/bug0068.pp | 9 + bugs/bug0069.pp | 25 + bugs/bug0070.pp | 10 + bugs/bug0071.pp | 5 + bugs/bug0072.pp | 15 + bugs/bug0073.pp | 30 + bugs/bug0074.pp | 28 + bugs/bug0075.pp | 31 + bugs/bug0076.pp | 24 + bugs/bug0077.pp | 9 + bugs/bug0077b.pp | 11 + bugs/bug0078.pp | 7 + bugs/bug0079.pp | 18 + bugs/bug0080.pp | 8 + bugs/bug0081.pp | 7 + bugs/bug0082.pp | 29 + bugs/bug0084.pp | 13 + bugs/bug0085.pp | 3 + bugs/bug0086.pp | 15 + bugs/bug0087.pp | 15 + bugs/bug0088.pp | 3 + bugs/bug0089.pp | 3 + bugs/bug0090.pp | 9 + bugs/bug0091.pp | 23 + bugs/bug0092.pp | 11 + bugs/bug0093.pp | 18 + bugs/bug0094.pp | 5 + bugs/bug0095.pp | 15 + bugs/bug0096.pp | 24 + bugs/bug0097.pp | 19 + bugs/bug0098.pp | 45 + bugs/bug0099.pp | 7 + bugs/bug0100.pp | 7 + bugs/bug0101.pp | 18 + bugs/bug0102.pp | 16 + bugs/bug0103.pp | 8 + bugs/bug0104.pp | 13 + bugs/bug0105.pp | 15 + bugs/bug0106.pp | 11 + bugs/bug0107.pp | 28 + bugs/bug0108.pp | 5 + bugs/bug0109.pp | 9 + bugs/bug0110.pp | 7 + bugs/bug0111.pp | 13 + bugs/bug0112.pp | 21 + bugs/bug0113.pp | 13 + bugs/bug0114.pp | 3 + bugs/bug0115.pp | 8 + bugs/bug0116.pp | 9 + bugs/readme.txt | 163 +++ docs/.log | 35 + docs/Makefile | 205 ++++ docs/README.DOCS | 51 + docs/crt.tex | 342 ++++++ docs/crtex/Makefile | 54 + docs/crtex/README | 21 + docs/crtex/ex1.pp | 13 + docs/crtex/ex10.pp | 18 + docs/crtex/ex11.pp | 19 + docs/crtex/ex12.pp | 14 + docs/crtex/ex13.pp | 15 + docs/crtex/ex14.pp | 13 + docs/crtex/ex15.pp | 15 + docs/crtex/ex16.pp | 18 + docs/crtex/ex2.pp | 11 + docs/crtex/ex3.pp | 23 + docs/crtex/ex4.pp | 13 + docs/crtex/ex5.pp | 21 + docs/crtex/ex6.pp | 13 + docs/crtex/ex7.pp | 8 + docs/crtex/ex8.pp | 11 + docs/crtex/ex9.pp | 12 + docs/crtex/foot.tex | 2 + docs/crtex/head.tex | 3 + docs/crtex/pp2tex | 5 + docs/dos.tex | 558 +++++++++ docs/dosex/Makefile | 54 + docs/dosex/README | 18 + docs/dosex/ex1.pp | 18 + docs/dosex/ex10.pp | 14 + docs/dosex/ex11.pp | 8 + docs/dosex/ex12.pp | 14 + docs/dosex/ex13.pp | 12 + docs/dosex/ex14.pp | 8 + docs/dosex/ex2.pp | 16 + docs/dosex/ex3.pp | 23 + docs/dosex/ex4.pp | 32 + docs/dosex/ex5.pp | 15 + docs/dosex/ex6.pp | 9 + docs/dosex/ex7.pp | 17 + docs/dosex/ex8.pp | 18 + docs/dosex/ex9.pp | 30 + docs/dosex/foot.tex | 2 + docs/dosex/head.tex | 3 + docs/dosex/newex | 9 + docs/dosex/pp2tex | 5 + docs/dosex/template.pp | 7 + docs/foot.sed | 1 + docs/fpctoc.html | 18 + docs/fpk-html.tex | 119 ++ docs/fpk.perl | 107 ++ docs/fpk.sty | 188 +++ docs/fpk.sty.doc | 66 ++ docs/fpkman.sty | 156 +++ docs/getopts.tex | 135 +++ docs/go32.tex | 666 +++++++++++ docs/graph.tex | 554 +++++++++ docs/html.sty | 360 ++++++ docs/linux.tex | 1963 +++++++++++++++++++++++++++++++ docs/linuxex/Makefile | 58 + docs/linuxex/README | 58 + docs/linuxex/ex1.pp | 10 + docs/linuxex/ex10.pp | 11 + docs/linuxex/ex11.pp | 12 + docs/linuxex/ex12.pp | 12 + docs/linuxex/ex13.pp | 11 + docs/linuxex/ex14.pp | 24 + docs/linuxex/ex15.pp | 14 + docs/linuxex/ex16.pp | 9 + docs/linuxex/ex17.pp | 9 + docs/linuxex/ex18.pp | 9 + docs/linuxex/ex19.pp | 19 + docs/linuxex/ex2.pp | 17 + docs/linuxex/ex20.pp | 46 + docs/linuxex/ex21.pp | 31 + docs/linuxex/ex22.pp | 33 + docs/linuxex/ex23.pp | 21 + docs/linuxex/ex24.pp | 28 + docs/linuxex/ex25.pp | 24 + docs/linuxex/ex26.pp | 13 + docs/linuxex/ex27.pp | 10 + docs/linuxex/ex28.pp | 39 + docs/linuxex/ex29.pp | 63 + docs/linuxex/ex3.pp | 13 + docs/linuxex/ex30.pp | 33 + docs/linuxex/ex31.pp | 15 + docs/linuxex/ex32.pp | 22 + docs/linuxex/ex33.pp | 25 + docs/linuxex/ex34.pp | 22 + docs/linuxex/ex35.pp | 46 + docs/linuxex/ex36.pp | 28 + docs/linuxex/ex37.pp | 33 + docs/linuxex/ex38.pp | 48 + docs/linuxex/ex39.pp | 9 + docs/linuxex/ex4.pp | 19 + docs/linuxex/ex40.pp | 9 + docs/linuxex/ex41.pp | 9 + docs/linuxex/ex42.pp | 22 + docs/linuxex/ex43.pp | 20 + docs/linuxex/ex44.pp | 9 + docs/linuxex/ex45.pp | 9 + docs/linuxex/ex46.pp | 9 + docs/linuxex/ex47.pp | 12 + docs/linuxex/ex48.pp | 12 + docs/linuxex/ex49.pp | 22 + docs/linuxex/ex5.pp | 12 + docs/linuxex/ex51.pp | 15 + docs/linuxex/ex52.pp | 11 + docs/linuxex/ex53.pp | 27 + docs/linuxex/ex54.pp | 15 + docs/linuxex/ex55.pp | 30 + docs/linuxex/ex6.pp | 12 + docs/linuxex/ex7.pp | 21 + docs/linuxex/ex8.pp | 20 + docs/linuxex/ex9.pp | 22 + docs/linuxex/foot.tex | 2 + docs/linuxex/head.tex | 3 + docs/linuxex/newex | 8 + docs/linuxex/pp2tex | 5 + docs/linuxex/readme.dif | 10 + docs/linuxex/template.pp | 8 + docs/makehtm | 8 + docs/mmx.tex | 93 ++ docs/onechap.tex | 38 + docs/optex/Makefile | 53 + docs/optex/README | 5 + docs/optex/foot.tex | 2 + docs/optex/head.tex | 3 + docs/optex/optex.pp | 92 ++ docs/optex/pp2tex | 5 + docs/printer.tex | 62 + docs/printex/Makefile | 53 + docs/printex/README | 5 + docs/printex/foot.tex | 2 + docs/printex/head.tex | 3 + docs/printex/pp2tex | 5 + docs/printex/printex.pp | 23 + docs/prog.tex | 2291 ++++++++++++++++++++++++++++++++++++ docs/progpdf.tex | 22 + docs/ref.tex | 2326 ++++++++++++++++++++++++++++++++++++ docs/refex/Makefile | 58 + docs/refex/README | 83 ++ docs/refex/bug1.pp | 11 + docs/refex/ex1.pp | 12 + docs/refex/ex10.pp | 9 + docs/refex/ex11.pp | 12 + docs/refex/ex12.pp | 12 + docs/refex/ex13.pp | 10 + docs/refex/ex14.pp | 23 + docs/refex/ex15.pp | 11 + docs/refex/ex16.pp | 37 + docs/refex/ex17.pp | 11 + docs/refex/ex18.pp | 22 + docs/refex/ex19.pp | 11 + docs/refex/ex2.pp | 14 + docs/refex/ex20.pp | 15 + docs/refex/ex21.pp | 40 + docs/refex/ex22.pp | 7 + docs/refex/ex23.pp | 30 + docs/refex/ex24.pp | 18 + docs/refex/ex25.pp | 16 + docs/refex/ex26.pp | 22 + docs/refex/ex27.pp | 10 + docs/refex/ex28.pp | 21 + docs/refex/ex29.pp | 10 + docs/refex/ex3.pp | 16 + docs/refex/ex30.pp | 9 + docs/refex/ex31.pp | 14 + docs/refex/ex32.pp | 23 + docs/refex/ex33.pp | 11 + docs/refex/ex34.pp | 8 + docs/refex/ex35.pp | 16 + docs/refex/ex36.pp | 15 + docs/refex/ex37.pp | 8 + docs/refex/ex38.pp | 13 + docs/refex/ex39.pp | 18 + docs/refex/ex4.pp | 10 + docs/refex/ex40.pp | 22 + docs/refex/ex41.pp | 17 + docs/refex/ex42.pp | 12 + docs/refex/ex43.pp | 10 + docs/refex/ex44.pp | 10 + docs/refex/ex45.pp | 17 + docs/refex/ex46.pp | 11 + docs/refex/ex47.pp | 8 + docs/refex/ex48.pp | 14 + docs/refex/ex49.pp | 24 + docs/refex/ex5.pp | 18 + docs/refex/ex50.pp | 25 + docs/refex/ex51.pp | 23 + docs/refex/ex52.pp | 17 + docs/refex/ex53.pp | 20 + docs/refex/ex54.pp | 10 + docs/refex/ex55.pp | 8 + docs/refex/ex56.pp | 27 + docs/refex/ex57.pp | 14 + docs/refex/ex58.pp | 15 + docs/refex/ex59.pp | 13 + docs/refex/ex6.pp | 23 + docs/refex/ex60.pp | 9 + docs/refex/ex61.pp | 28 + docs/refex/ex62.pp | 8 + docs/refex/ex63.pp | 11 + docs/refex/ex64.pp | 9 + docs/refex/ex65.pp | 9 + docs/refex/ex66.pp | 8 + docs/refex/ex67.pp | 8 + docs/refex/ex68.pp | 18 + docs/refex/ex69.pp | 16 + docs/refex/ex7.pp | 11 + docs/refex/ex70.pp | 10 + docs/refex/ex71.pp | 22 + docs/refex/ex72.pp | 13 + docs/refex/ex73.pp | 12 + docs/refex/ex74.pp | 12 + docs/refex/ex75.pp | 18 + docs/refex/ex76.pp | 10 + docs/refex/ex77.pp | 9 + docs/refex/ex8.pp | 8 + docs/refex/ex9.pp | 15 + docs/refex/foot.tex | 2 + docs/refex/head.tex | 3 + docs/refex/make1tex | 10 + docs/refex/newex | 8 + docs/refex/pp2tex | 5 + docs/refex/pp2tex.bat | 6 + docs/refex/template.pp | 6 + docs/refpdf.tex | 22 + docs/sockets.tex | 429 +++++++ docs/sockex/Makefile | 53 + docs/sockex/README | 7 + docs/sockex/foot.tex | 2 + docs/sockex/head.tex | 3 + docs/sockex/pp2tex | 5 + docs/sockex/sock_cli.pp | 40 + docs/sockex/sock_svr.pp | 49 + docs/stringex/Makefile | 53 + docs/stringex/README | 20 + docs/stringex/ex1.pp | 12 + docs/stringex/ex10.pp | 16 + docs/stringex/ex11.pp | 16 + docs/stringex/ex12.pp | 17 + docs/stringex/ex13.pp | 13 + docs/stringex/ex14.pp | 15 + docs/stringex/ex15.pp | 11 + docs/stringex/ex16.pp | 17 + docs/stringex/ex17.pp | 18 + docs/stringex/ex2.pp | 17 + docs/stringex/ex3.pp | 14 + docs/stringex/ex4.pp | 18 + docs/stringex/ex5.pp | 14 + docs/stringex/ex6.pp | 17 + docs/stringex/ex7.pp | 14 + docs/stringex/ex8.pp | 20 + docs/stringex/ex9.pp | 20 + docs/stringex/foot.tex | 2 + docs/stringex/head.tex | 3 + docs/stringex/newex | 8 + docs/stringex/pp2tex | 5 + docs/stringex/template.pp | 8 + docs/strings.tex | 256 ++++ docs/units.tex | 101 ++ docs/unitspdf.tex | 22 + docs/user.tex | 2343 +++++++++++++++++++++++++++++++++++++ docs/userpdf.tex | 22 + 387 files changed, 19816 insertions(+) create mode 100644 bugs/BUG0052.PP create mode 100644 bugs/BUG0083.PP create mode 100644 bugs/bug0001.pp create mode 100644 bugs/bug0002.pp create mode 100644 bugs/bug0003.pp create mode 100644 bugs/bug0004.pp create mode 100644 bugs/bug0005.pp create mode 100644 bugs/bug00051.pp create mode 100644 bugs/bug0006.pp create mode 100644 bugs/bug00061.pp create mode 100644 bugs/bug0007.pp create mode 100644 bugs/bug0008.pp create mode 100644 bugs/bug0009.pp create mode 100644 bugs/bug0010.pp create mode 100644 bugs/bug0011.pp create mode 100644 bugs/bug0012.pp create mode 100644 bugs/bug0013.pp create mode 100644 bugs/bug0014.pp create mode 100644 bugs/bug00141.pp create mode 100644 bugs/bug0015.pp create mode 100644 bugs/bug0016.pp create mode 100644 bugs/bug0017.pp create mode 100644 bugs/bug0018.pp create mode 100644 bugs/bug0019.pp create mode 100644 bugs/bug0020.pp create mode 100644 bugs/bug0021.pp create mode 100644 bugs/bug0022.pp create mode 100644 bugs/bug0023.pp create mode 100644 bugs/bug0024.pp create mode 100644 bugs/bug0025.pp create mode 100644 bugs/bug0026.pp create mode 100644 bugs/bug0027.pp create mode 100644 bugs/bug0028.pp create mode 100644 bugs/bug0029.pp create mode 100644 bugs/bug0030.pp create mode 100644 bugs/bug0031.pp create mode 100644 bugs/bug0032.pp create mode 100644 bugs/bug0033.pp create mode 100644 bugs/bug0034.pp create mode 100644 bugs/bug0035.pp create mode 100644 bugs/bug0036.pp create mode 100644 bugs/bug0037.pp create mode 100644 bugs/bug0038.pp create mode 100644 bugs/bug0039.pp create mode 100644 bugs/bug0040.pp create mode 100644 bugs/bug0041.pp create mode 100644 bugs/bug0042.pp create mode 100644 bugs/bug0043.pp create mode 100644 bugs/bug0044.pp create mode 100644 bugs/bug0045.pp create mode 100644 bugs/bug0046.pp create mode 100644 bugs/bug0047.pp create mode 100644 bugs/bug0048.pp create mode 100644 bugs/bug0049.pp create mode 100644 bugs/bug0050.pp create mode 100644 bugs/bug0051.pp create mode 100644 bugs/bug0053.pp create mode 100644 bugs/bug0054.pp create mode 100644 bugs/bug0055.pp create mode 100644 bugs/bug0056.pp create mode 100644 bugs/bug0057.pp create mode 100644 bugs/bug0058.pp create mode 100644 bugs/bug0059.pp create mode 100644 bugs/bug0060.pp create mode 100644 bugs/bug0061.pp create mode 100644 bugs/bug0062.pp create mode 100644 bugs/bug0063.pp create mode 100644 bugs/bug0064.pp create mode 100644 bugs/bug0065.pp create mode 100644 bugs/bug0066.pp create mode 100644 bugs/bug0067.pp create mode 100644 bugs/bug0067b.pp create mode 100644 bugs/bug0068.pp create mode 100644 bugs/bug0069.pp create mode 100644 bugs/bug0070.pp create mode 100644 bugs/bug0071.pp create mode 100644 bugs/bug0072.pp create mode 100644 bugs/bug0073.pp create mode 100644 bugs/bug0074.pp create mode 100644 bugs/bug0075.pp create mode 100644 bugs/bug0076.pp create mode 100644 bugs/bug0077.pp create mode 100644 bugs/bug0077b.pp create mode 100644 bugs/bug0078.pp create mode 100644 bugs/bug0079.pp create mode 100644 bugs/bug0080.pp create mode 100644 bugs/bug0081.pp create mode 100644 bugs/bug0082.pp create mode 100644 bugs/bug0084.pp create mode 100644 bugs/bug0085.pp create mode 100644 bugs/bug0086.pp create mode 100644 bugs/bug0087.pp create mode 100644 bugs/bug0088.pp create mode 100644 bugs/bug0089.pp create mode 100644 bugs/bug0090.pp create mode 100644 bugs/bug0091.pp create mode 100644 bugs/bug0092.pp create mode 100644 bugs/bug0093.pp create mode 100644 bugs/bug0094.pp create mode 100644 bugs/bug0095.pp create mode 100644 bugs/bug0096.pp create mode 100644 bugs/bug0097.pp create mode 100644 bugs/bug0098.pp create mode 100644 bugs/bug0099.pp create mode 100644 bugs/bug0100.pp create mode 100644 bugs/bug0101.pp create mode 100644 bugs/bug0102.pp create mode 100644 bugs/bug0103.pp create mode 100644 bugs/bug0104.pp create mode 100644 bugs/bug0105.pp create mode 100644 bugs/bug0106.pp create mode 100644 bugs/bug0107.pp create mode 100644 bugs/bug0108.pp create mode 100644 bugs/bug0109.pp create mode 100644 bugs/bug0110.pp create mode 100644 bugs/bug0111.pp create mode 100644 bugs/bug0112.pp create mode 100644 bugs/bug0113.pp create mode 100644 bugs/bug0114.pp create mode 100644 bugs/bug0115.pp create mode 100644 bugs/bug0116.pp create mode 100644 bugs/readme.txt create mode 100644 docs/.log create mode 100644 docs/Makefile create mode 100644 docs/README.DOCS create mode 100644 docs/crt.tex create mode 100644 docs/crtex/Makefile create mode 100644 docs/crtex/README create mode 100644 docs/crtex/ex1.pp create mode 100644 docs/crtex/ex10.pp create mode 100644 docs/crtex/ex11.pp create mode 100644 docs/crtex/ex12.pp create mode 100644 docs/crtex/ex13.pp create mode 100644 docs/crtex/ex14.pp create mode 100644 docs/crtex/ex15.pp create mode 100644 docs/crtex/ex16.pp create mode 100644 docs/crtex/ex2.pp create mode 100644 docs/crtex/ex3.pp create mode 100644 docs/crtex/ex4.pp create mode 100644 docs/crtex/ex5.pp create mode 100644 docs/crtex/ex6.pp create mode 100644 docs/crtex/ex7.pp create mode 100644 docs/crtex/ex8.pp create mode 100644 docs/crtex/ex9.pp create mode 100644 docs/crtex/foot.tex create mode 100644 docs/crtex/head.tex create mode 100644 docs/crtex/pp2tex create mode 100644 docs/dos.tex create mode 100644 docs/dosex/Makefile create mode 100644 docs/dosex/README create mode 100644 docs/dosex/ex1.pp create mode 100644 docs/dosex/ex10.pp create mode 100644 docs/dosex/ex11.pp create mode 100644 docs/dosex/ex12.pp create mode 100644 docs/dosex/ex13.pp create mode 100644 docs/dosex/ex14.pp create mode 100644 docs/dosex/ex2.pp create mode 100644 docs/dosex/ex3.pp create mode 100644 docs/dosex/ex4.pp create mode 100644 docs/dosex/ex5.pp create mode 100644 docs/dosex/ex6.pp create mode 100644 docs/dosex/ex7.pp create mode 100644 docs/dosex/ex8.pp create mode 100644 docs/dosex/ex9.pp create mode 100644 docs/dosex/foot.tex create mode 100644 docs/dosex/head.tex create mode 100644 docs/dosex/newex create mode 100644 docs/dosex/pp2tex create mode 100644 docs/dosex/template.pp create mode 100644 docs/foot.sed create mode 100644 docs/fpctoc.html create mode 100644 docs/fpk-html.tex create mode 100644 docs/fpk.perl create mode 100644 docs/fpk.sty create mode 100644 docs/fpk.sty.doc create mode 100644 docs/fpkman.sty create mode 100644 docs/getopts.tex create mode 100644 docs/go32.tex create mode 100644 docs/graph.tex create mode 100644 docs/html.sty create mode 100644 docs/linux.tex create mode 100644 docs/linuxex/Makefile create mode 100644 docs/linuxex/README create mode 100644 docs/linuxex/ex1.pp create mode 100644 docs/linuxex/ex10.pp create mode 100644 docs/linuxex/ex11.pp create mode 100644 docs/linuxex/ex12.pp create mode 100644 docs/linuxex/ex13.pp create mode 100644 docs/linuxex/ex14.pp create mode 100644 docs/linuxex/ex15.pp create mode 100644 docs/linuxex/ex16.pp create mode 100644 docs/linuxex/ex17.pp create mode 100644 docs/linuxex/ex18.pp create mode 100644 docs/linuxex/ex19.pp create mode 100644 docs/linuxex/ex2.pp create mode 100644 docs/linuxex/ex20.pp create mode 100644 docs/linuxex/ex21.pp create mode 100644 docs/linuxex/ex22.pp create mode 100644 docs/linuxex/ex23.pp create mode 100644 docs/linuxex/ex24.pp create mode 100644 docs/linuxex/ex25.pp create mode 100644 docs/linuxex/ex26.pp create mode 100644 docs/linuxex/ex27.pp create mode 100644 docs/linuxex/ex28.pp create mode 100644 docs/linuxex/ex29.pp create mode 100644 docs/linuxex/ex3.pp create mode 100644 docs/linuxex/ex30.pp create mode 100644 docs/linuxex/ex31.pp create mode 100644 docs/linuxex/ex32.pp create mode 100644 docs/linuxex/ex33.pp create mode 100644 docs/linuxex/ex34.pp create mode 100644 docs/linuxex/ex35.pp create mode 100644 docs/linuxex/ex36.pp create mode 100644 docs/linuxex/ex37.pp create mode 100644 docs/linuxex/ex38.pp create mode 100644 docs/linuxex/ex39.pp create mode 100644 docs/linuxex/ex4.pp create mode 100644 docs/linuxex/ex40.pp create mode 100644 docs/linuxex/ex41.pp create mode 100644 docs/linuxex/ex42.pp create mode 100644 docs/linuxex/ex43.pp create mode 100644 docs/linuxex/ex44.pp create mode 100644 docs/linuxex/ex45.pp create mode 100644 docs/linuxex/ex46.pp create mode 100644 docs/linuxex/ex47.pp create mode 100644 docs/linuxex/ex48.pp create mode 100644 docs/linuxex/ex49.pp create mode 100644 docs/linuxex/ex5.pp create mode 100644 docs/linuxex/ex51.pp create mode 100644 docs/linuxex/ex52.pp create mode 100644 docs/linuxex/ex53.pp create mode 100644 docs/linuxex/ex54.pp create mode 100644 docs/linuxex/ex55.pp create mode 100644 docs/linuxex/ex6.pp create mode 100644 docs/linuxex/ex7.pp create mode 100644 docs/linuxex/ex8.pp create mode 100644 docs/linuxex/ex9.pp create mode 100644 docs/linuxex/foot.tex create mode 100644 docs/linuxex/head.tex create mode 100644 docs/linuxex/newex create mode 100644 docs/linuxex/pp2tex create mode 100644 docs/linuxex/readme.dif create mode 100644 docs/linuxex/template.pp create mode 100644 docs/makehtm create mode 100644 docs/mmx.tex create mode 100644 docs/onechap.tex create mode 100644 docs/optex/Makefile create mode 100644 docs/optex/README create mode 100644 docs/optex/foot.tex create mode 100644 docs/optex/head.tex create mode 100644 docs/optex/optex.pp create mode 100644 docs/optex/pp2tex create mode 100644 docs/printer.tex create mode 100644 docs/printex/Makefile create mode 100644 docs/printex/README create mode 100644 docs/printex/foot.tex create mode 100644 docs/printex/head.tex create mode 100644 docs/printex/pp2tex create mode 100644 docs/printex/printex.pp create mode 100644 docs/prog.tex create mode 100644 docs/progpdf.tex create mode 100644 docs/ref.tex create mode 100644 docs/refex/Makefile create mode 100644 docs/refex/README create mode 100644 docs/refex/bug1.pp create mode 100644 docs/refex/ex1.pp create mode 100644 docs/refex/ex10.pp create mode 100644 docs/refex/ex11.pp create mode 100644 docs/refex/ex12.pp create mode 100644 docs/refex/ex13.pp create mode 100644 docs/refex/ex14.pp create mode 100644 docs/refex/ex15.pp create mode 100644 docs/refex/ex16.pp create mode 100644 docs/refex/ex17.pp create mode 100644 docs/refex/ex18.pp create mode 100644 docs/refex/ex19.pp create mode 100644 docs/refex/ex2.pp create mode 100644 docs/refex/ex20.pp create mode 100644 docs/refex/ex21.pp create mode 100644 docs/refex/ex22.pp create mode 100644 docs/refex/ex23.pp create mode 100644 docs/refex/ex24.pp create mode 100644 docs/refex/ex25.pp create mode 100644 docs/refex/ex26.pp create mode 100644 docs/refex/ex27.pp create mode 100644 docs/refex/ex28.pp create mode 100644 docs/refex/ex29.pp create mode 100644 docs/refex/ex3.pp create mode 100644 docs/refex/ex30.pp create mode 100644 docs/refex/ex31.pp create mode 100644 docs/refex/ex32.pp create mode 100644 docs/refex/ex33.pp create mode 100644 docs/refex/ex34.pp create mode 100644 docs/refex/ex35.pp create mode 100644 docs/refex/ex36.pp create mode 100644 docs/refex/ex37.pp create mode 100644 docs/refex/ex38.pp create mode 100644 docs/refex/ex39.pp create mode 100644 docs/refex/ex4.pp create mode 100644 docs/refex/ex40.pp create mode 100644 docs/refex/ex41.pp create mode 100644 docs/refex/ex42.pp create mode 100644 docs/refex/ex43.pp create mode 100644 docs/refex/ex44.pp create mode 100644 docs/refex/ex45.pp create mode 100644 docs/refex/ex46.pp create mode 100644 docs/refex/ex47.pp create mode 100644 docs/refex/ex48.pp create mode 100644 docs/refex/ex49.pp create mode 100644 docs/refex/ex5.pp create mode 100644 docs/refex/ex50.pp create mode 100644 docs/refex/ex51.pp create mode 100644 docs/refex/ex52.pp create mode 100644 docs/refex/ex53.pp create mode 100644 docs/refex/ex54.pp create mode 100644 docs/refex/ex55.pp create mode 100644 docs/refex/ex56.pp create mode 100644 docs/refex/ex57.pp create mode 100644 docs/refex/ex58.pp create mode 100644 docs/refex/ex59.pp create mode 100644 docs/refex/ex6.pp create mode 100644 docs/refex/ex60.pp create mode 100644 docs/refex/ex61.pp create mode 100644 docs/refex/ex62.pp create mode 100644 docs/refex/ex63.pp create mode 100644 docs/refex/ex64.pp create mode 100644 docs/refex/ex65.pp create mode 100644 docs/refex/ex66.pp create mode 100644 docs/refex/ex67.pp create mode 100644 docs/refex/ex68.pp create mode 100644 docs/refex/ex69.pp create mode 100644 docs/refex/ex7.pp create mode 100644 docs/refex/ex70.pp create mode 100644 docs/refex/ex71.pp create mode 100644 docs/refex/ex72.pp create mode 100644 docs/refex/ex73.pp create mode 100644 docs/refex/ex74.pp create mode 100644 docs/refex/ex75.pp create mode 100644 docs/refex/ex76.pp create mode 100644 docs/refex/ex77.pp create mode 100644 docs/refex/ex8.pp create mode 100644 docs/refex/ex9.pp create mode 100644 docs/refex/foot.tex create mode 100644 docs/refex/head.tex create mode 100644 docs/refex/make1tex create mode 100644 docs/refex/newex create mode 100644 docs/refex/pp2tex create mode 100644 docs/refex/pp2tex.bat create mode 100644 docs/refex/template.pp create mode 100644 docs/refpdf.tex create mode 100644 docs/sockets.tex create mode 100644 docs/sockex/Makefile create mode 100644 docs/sockex/README create mode 100644 docs/sockex/foot.tex create mode 100644 docs/sockex/head.tex create mode 100644 docs/sockex/pp2tex create mode 100644 docs/sockex/sock_cli.pp create mode 100644 docs/sockex/sock_svr.pp create mode 100644 docs/stringex/Makefile create mode 100644 docs/stringex/README create mode 100644 docs/stringex/ex1.pp create mode 100644 docs/stringex/ex10.pp create mode 100644 docs/stringex/ex11.pp create mode 100644 docs/stringex/ex12.pp create mode 100644 docs/stringex/ex13.pp create mode 100644 docs/stringex/ex14.pp create mode 100644 docs/stringex/ex15.pp create mode 100644 docs/stringex/ex16.pp create mode 100644 docs/stringex/ex17.pp create mode 100644 docs/stringex/ex2.pp create mode 100644 docs/stringex/ex3.pp create mode 100644 docs/stringex/ex4.pp create mode 100644 docs/stringex/ex5.pp create mode 100644 docs/stringex/ex6.pp create mode 100644 docs/stringex/ex7.pp create mode 100644 docs/stringex/ex8.pp create mode 100644 docs/stringex/ex9.pp create mode 100644 docs/stringex/foot.tex create mode 100644 docs/stringex/head.tex create mode 100644 docs/stringex/newex create mode 100644 docs/stringex/pp2tex create mode 100644 docs/stringex/template.pp create mode 100644 docs/strings.tex create mode 100644 docs/units.tex create mode 100644 docs/unitspdf.tex create mode 100644 docs/user.tex create mode 100644 docs/userpdf.tex diff --git a/bugs/BUG0052.PP b/bugs/BUG0052.PP new file mode 100644 index 0000000000..287d1df3e3 --- /dev/null +++ b/bugs/BUG0052.PP @@ -0,0 +1,20 @@ +const + Triangle: array[1..4] of PointType = ((X: 50; Y: 100), (X: 100; Y:100), + (X: 150; Y: 150), (X: 50; Y: 100)); + +begin + graphdefaults; + drawpoly +var Gd, Gm: Integer; +begin + Gd := Detect; + InitGraph(Gd, Gm, ''); + if GraphResult <> grOk then + Halt(1); + drawpoly(SizeOf(Triangle) div SizeOf(PointType), Triangle); + readln; + fillpoly(SizeOf(Triangle) div SizeOf(PointType), Triangle); + graphdefaults; + readln; + CloseGraph; +end. diff --git a/bugs/BUG0083.PP b/bugs/BUG0083.PP new file mode 100644 index 0000000000..4bd2cdd673 --- /dev/null +++ b/bugs/BUG0083.PP @@ -0,0 +1,8 @@ + +var + s1 : set of char; + c1,c2,c3 : char; + +begin + s1:=[c1..c2,c3]; +end. diff --git a/bugs/bug0001.pp b/bugs/bug0001.pp new file mode 100644 index 0000000000..06f1a4d38d --- /dev/null +++ b/bugs/bug0001.pp @@ -0,0 +1,8 @@ +program smalltest; + const + teststr : string = ' '#9#255#0; +begin + writeln(teststr); + teststr := 'gaga'; + writeln(teststr); +end. diff --git a/bugs/bug0002.pp b/bugs/bug0002.pp new file mode 100644 index 0000000000..6b1b637b91 --- /dev/null +++ b/bugs/bug0002.pp @@ -0,0 +1,83 @@ +unit bug0002; + + interface + + implementation + +{$message starting hexstr} + function hexstr(val : longint;cnt : byte) : string; + + const + hexval : string[16]=('0123456789ABCDEF'); + + var + s : string; + l2,i : integer; + l1 : longInt; + + begin + s[0]:=char(cnt); + l1:=longint($f) shl (4*(cnt-1)); + for i:=1 to cnt do + begin + l2:=(val and l1) shr (4*(cnt-i)); + l1:=l1 shr 4; + s[i]:=hexval[l2+1]; + end; + hexstr:=s; + end; + +{$message starting dump_stack} + + procedure dump_stack(bp : longint); + +{$message starting get_next_frame} + + function get_next_frame(bp : longint) : longint; + + begin + asm + movl bp,%eax + movl (%eax),%eax + movl %eax,__RESULT + end ['EAX']; + end; + + procedure dump_frame(addr : longint); + + begin + { to be used by symify } + writeln(' 0x',HexStr(addr,8)); + end; + +{$message starting get_addr} + + function get_addr(BP : longint) : longint; + + begin + asm + movl BP,%eax + movl 4(%eax),%eax + movl %eax,__RESULT + end ['EAX']; + end; + +{$message starting main} + + var + i,prevbp : longint; + + begin + prevbp:=bp-1; + i:=0; + while bp > prevbp do + begin + dump_frame(get_addr(bp)); + i:=i+1; + if i>max_frame_dump then exit; + prevbp:=bp; + bp:=get_next_frame(bp); + end; + end; + +end. diff --git a/bugs/bug0003.pp b/bugs/bug0003.pp new file mode 100644 index 0000000000..41bccce9f6 --- /dev/null +++ b/bugs/bug0003.pp @@ -0,0 +1,18 @@ +unit bug0002; + + interface + + implementation + + + procedure dump_stack(bp : longint); + + function get_next_frame(bp : longint) : longint; + + begin + end; + + begin + end; + +end. diff --git a/bugs/bug0004.pp b/bugs/bug0004.pp new file mode 100644 index 0000000000..f3d180fe89 --- /dev/null +++ b/bugs/bug0004.pp @@ -0,0 +1,12 @@ +var + i : longint; + +begin + for i:=1 to 100 do + begin + writeln('Hello'); + continue; + writeln('ohh'); + end; +end. + diff --git a/bugs/bug0005.pp b/bugs/bug0005.pp new file mode 100644 index 0000000000..58237cd8cc --- /dev/null +++ b/bugs/bug0005.pp @@ -0,0 +1,8 @@ +begin + if 1=1 then + begin + end; + if 1<>1 then + begin + end; +end. diff --git a/bugs/bug00051.pp b/bugs/bug00051.pp new file mode 100644 index 0000000000..dacc065ede --- /dev/null +++ b/bugs/bug00051.pp @@ -0,0 +1,6 @@ +var + b : boolean; + +begin + b:=1<>1; +end. diff --git a/bugs/bug0006.pp b/bugs/bug0006.pp new file mode 100644 index 0000000000..457c844842 --- /dev/null +++ b/bugs/bug0006.pp @@ -0,0 +1,14 @@ +var + a,b,c,d,e,f,g,r : double; + +begin + a:=10.0; + b:=11.0; + c:=13.0; + d:=17.0; + e:=19.0; + f:=23.0; + r:=2.0; + a:= a - 2*b*e - 2*c*f - 2*d*g - Sqr(r); + writeln(a,' (must be -1010)'); +end. diff --git a/bugs/bug00061.pp b/bugs/bug00061.pp new file mode 100644 index 0000000000..55cb7e4f5a --- /dev/null +++ b/bugs/bug00061.pp @@ -0,0 +1,8 @@ +var + r : double; + s : string; + +begin + r:=1234.0; + str(r,s); +end. diff --git a/bugs/bug0007.pp b/bugs/bug0007.pp new file mode 100644 index 0000000000..0a567154b3 --- /dev/null +++ b/bugs/bug0007.pp @@ -0,0 +1,10 @@ +var + count : byte; + +begin + for count:=1 to 127 do + begin + writeln(count,'. loop'); + end; +end. + diff --git a/bugs/bug0008.pp b/bugs/bug0008.pp new file mode 100644 index 0000000000..af7b850af8 --- /dev/null +++ b/bugs/bug0008.pp @@ -0,0 +1,6 @@ +const + compilerconst=1; + +begin + dec(compilerconst); +end. diff --git a/bugs/bug0009.pp b/bugs/bug0009.pp new file mode 100644 index 0000000000..2ca26f27f6 --- /dev/null +++ b/bugs/bug0009.pp @@ -0,0 +1,16 @@ +var c:byte; + + Procedure a(b:boolean); + + begin + if b then writeln('TRUE') else writeln('FALSE'); + end; + + begin {main program} + a(true); {works} + a(false); {works} + c:=0; + a(c>0); {doesn't work} + a(c<0); {doesn't work} + a(c=0); + end. diff --git a/bugs/bug0010.pp b/bugs/bug0010.pp new file mode 100644 index 0000000000..bcca061be9 --- /dev/null +++ b/bugs/bug0010.pp @@ -0,0 +1,6 @@ +program hello; + + begin + writeln('Hello); + end. + diff --git a/bugs/bug0011.pp b/bugs/bug0011.pp new file mode 100644 index 0000000000..d1c1d29fa5 --- /dev/null +++ b/bugs/bug0011.pp @@ -0,0 +1,13 @@ +var + vga : array[0..320*200-1] of byte; + +procedure test(x,y : longint); + + begin + vga[x+y mod 320]:=random(256); + vga[x+y mod 320]:=random(256); + end; + +begin +end. + diff --git a/bugs/bug0012.pp b/bugs/bug0012.pp new file mode 100644 index 0000000000..4902b943de --- /dev/null +++ b/bugs/bug0012.pp @@ -0,0 +1,10 @@ +var + a,b : longint; + +begin + a:=1; + b:=2; + if byte(a>b)=byte(ahabs then + begin + mi:=i; + mj:=j; + habs:=abs(phi[mi,mj]); + end; + { calculate error } + sigma_phi:=sigma_phi+abs(phi[i,j]); + end; + adapt(mi,mj); + gotoxy(1,23); + textcolor(white); + writeln(iter,' iterations, sigma_phi=',sigma_phi); + until keypressed or (sigma_phi<0.5); + draw; + gotoxy(1,23); + textcolor(white); + writeln(iter,' iterations, sigma_phi=',sigma_phi); + writeln('press a key'); + if readkey=#0 then + readkey; + end. diff --git a/bugs/bug0017.pp b/bugs/bug0017.pp new file mode 100644 index 0000000000..eefa916f6e --- /dev/null +++ b/bugs/bug0017.pp @@ -0,0 +1,27 @@ + procedure init; + + var + endofparas : boolean; + + procedure getparastring; + + procedure nextopt; + + begin + getparastring; + init; + endofparas:=false; + end; + + begin + nextopt; + end; + + begin + getparastring; + end; + +begin + init; +end. + diff --git a/bugs/bug0018.pp b/bugs/bug0018.pp new file mode 100644 index 0000000000..49c676c1e1 --- /dev/null +++ b/bugs/bug0018.pp @@ -0,0 +1,11 @@ +type + p = ^x; + x = byte; + +var + b : p; + +begin + b^:=12; +end. + diff --git a/bugs/bug0019.pp b/bugs/bug0019.pp new file mode 100644 index 0000000000..ed6f8990a5 --- /dev/null +++ b/bugs/bug0019.pp @@ -0,0 +1,12 @@ +type + b = ^x; + + x = byte; + +var + pb : b; + +begin + pb^:=10; +end. + diff --git a/bugs/bug0020.pp b/bugs/bug0020.pp new file mode 100644 index 0000000000..df977e9029 --- /dev/null +++ b/bugs/bug0020.pp @@ -0,0 +1,26 @@ +uses + Gpm; + +var + Conn: TGPMConnect; + Quit: Boolean; + Event: TGPMEvent; + +begin + + FillChar(Conn, SizeOf(Conn), 0); + Conn.EventMask := GPM_MOVE+GPM_DRAG+GPM_DOWN+GPM_UP+GPM_SINGLE+GPM_DOUBLE; + Conn.DefaultMask := 0; + GPM_Open(Conn, 0); + WriteLn('I have opened the mouse... trying to do something tricky...'); + Quit := False; + while not Quit do begin + GPM_GetEvent(Event); + WriteLn('GetEvent returned... Event.EventType=', Event.EventType); + if Event.EventType and GPM_BARE_EVENTS = GPM_DOWN then begin + WriteLn('You have pressed a mouse button...'); + Quit := True; + end; + end; + GPM_Close; +end. \ No newline at end of file diff --git a/bugs/bug0021.pp b/bugs/bug0021.pp new file mode 100644 index 0000000000..f2148818a5 --- /dev/null +++ b/bugs/bug0021.pp @@ -0,0 +1,39 @@ +{ tests constant set evalution } + +var + a : set of byte; + +const + b : set of byte = [0..255]+[9]; + +type + tcommandset = set of byte; + +const +cmZoom = 10; +cmClose = 5; +cmResize = 8; +cmNext = 12; +cmPrev = 15; + +CONST + CurCommandSet : TCommandSet = ([0..255] - + [cmZoom, cmClose, cmResize, cmNext, cmPrev]); + commands : tcommandset = []; + +var + CommandSetChanged : boolean; + +PROCEDURE DisableCommands (Commands: TCommandSet); + + BEGIN + {$IFNDEF PPC_FPK} { FPK bug } + CommandSetChanged := CommandSetChanged OR + (CurCommandSet * Commands <> []); { Set changed flag } + {$ENDIF} + CurCommandSet := CurCommandSet - Commands; { Update command set } + END; + +begin + a:=[byte(1)]+[byte(2)]; +end. \ No newline at end of file diff --git a/bugs/bug0022.pp b/bugs/bug0022.pp new file mode 100644 index 0000000000..f64490b248 --- /dev/null +++ b/bugs/bug0022.pp @@ -0,0 +1,29 @@ +type + tobject = object + procedure x; + constructor c; + end; + +procedure a; + + begin + end; + +procedure tobject.x; + + begin + end; + +constructor tobject.c; + + begin + end; + +var + p : pointer; + +begin + p:=@a; + p:=@tobject.x; + p:=@tobject.c; +end. diff --git a/bugs/bug0023.pp b/bugs/bug0023.pp new file mode 100644 index 0000000000..39388a7a4f --- /dev/null +++ b/bugs/bug0023.pp @@ -0,0 +1,47 @@ +type + tobject = object + a : longint; + procedure t1; + procedure t2;virtual; + constructor init; + end; + +procedure tobject.t1; + + procedure nested1; + + begin + writeln; + a:=1; + end; + + begin + end; + +procedure tobject.t2; + + procedure nested1; + + begin + writeln; + a:=1; + end; + + begin + end; + +constructor tobject.init; + + procedure nested1; + + begin + writeln; + a:=1; + end; + + begin + end; + + +begin +end. \ No newline at end of file diff --git a/bugs/bug0024.pp b/bugs/bug0024.pp new file mode 100644 index 0000000000..a5b95f7487 --- /dev/null +++ b/bugs/bug0024.pp @@ -0,0 +1,24 @@ + +type + charset=set of char; + + trec=record + junk : array[1..32] of byte; + t : charset; + end; + + var + tr : trec; + tp : ^trec; + + + procedure Crash(const k:charset); + + begin + tp^.t:=[#7..#10]+k; + end; + + begin + tp:=@tr; + Crash([#20..#32]); + end. \ No newline at end of file diff --git a/bugs/bug0025.pp b/bugs/bug0025.pp new file mode 100644 index 0000000000..81088f0298 --- /dev/null +++ b/bugs/bug0025.pp @@ -0,0 +1,15 @@ +procedure p1; +type + datetime=record + junk : string; +end; +var + dt : datetime; +begin + fillchar(dt,sizeof(dt),0); +end; + +begin + P1; +end. + diff --git a/bugs/bug0026.pp b/bugs/bug0026.pp new file mode 100644 index 0000000000..13dcccccae --- /dev/null +++ b/bugs/bug0026.pp @@ -0,0 +1,22 @@ +const + HexTbl : array[0..15] of char=('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); +function HexB(b:byte):string; +begin + HexB[0]:=#2; + HexB[1]:=HexTbl[b shr 4]; + HexB[2]:=HexTbl[b and $f]; +end; + + + +function HexW(w:word):string; +begin + HexW:=HexB(w shr 8)+HexB(w and $ff); +end; + + + +begin + HexW($fff); +end. + diff --git a/bugs/bug0027.pp b/bugs/bug0027.pp new file mode 100644 index 0000000000..5cd4e28c3f --- /dev/null +++ b/bugs/bug0027.pp @@ -0,0 +1,5 @@ +type enumtype = (One, two, three, forty:=40, fifty); + +begin +end. + diff --git a/bugs/bug0028.pp b/bugs/bug0028.pp new file mode 100644 index 0000000000..4cf2d0e261 --- /dev/null +++ b/bugs/bug0028.pp @@ -0,0 +1,10 @@ +type + enumtype = (a); + +var + e : enumtype; + +begin + writeln(ord(e)); +end. + diff --git a/bugs/bug0029.pp b/bugs/bug0029.pp new file mode 100644 index 0000000000..cf340d7c9d --- /dev/null +++ b/bugs/bug0029.pp @@ -0,0 +1,10 @@ +type + TA = object + end; + +var + P: Pointer; + +begin + P := pointer(TypeOf(TA)); +end. diff --git a/bugs/bug0030.pp b/bugs/bug0030.pp new file mode 100644 index 0000000000..19c4a7e21d --- /dev/null +++ b/bugs/bug0030.pp @@ -0,0 +1,6 @@ +const + a : array[0..1] of real = (1,1); + +begin +end. + diff --git a/bugs/bug0031.pp b/bugs/bug0031.pp new file mode 100644 index 0000000000..916fd8e955 --- /dev/null +++ b/bugs/bug0031.pp @@ -0,0 +1,8 @@ +var + a : array[boolean] of longint; + +begin + a[true]:=1234; + a[false]:=123; +end. + diff --git a/bugs/bug0032.pp b/bugs/bug0032.pp new file mode 100644 index 0000000000..b53d723171 --- /dev/null +++ b/bugs/bug0032.pp @@ -0,0 +1,6 @@ +var + p : procedure(w : word); + +begin + p(1234); +end. diff --git a/bugs/bug0033.pp b/bugs/bug0033.pp new file mode 100644 index 0000000000..705351c32e --- /dev/null +++ b/bugs/bug0033.pp @@ -0,0 +1,13 @@ +var + p1 : pchar; + p2 : array[0..10] of char; + s : string; + c : char; + +begin + p1:='c'; + s:='c'; + { this isn't allowed + p1:=c; + } +end. diff --git a/bugs/bug0034.pp b/bugs/bug0034.pp new file mode 100644 index 0000000000..03103cbc8c --- /dev/null +++ b/bugs/bug0034.pp @@ -0,0 +1,12 @@ +begin + asm + movl %eax,%eax + movl %eax,%eax + movl %eax,%eax + movl %eax,%eax + movl %eax,%eax + movl %eax,%eax + movl %eax,%eax + end ; + i:=0; +end. diff --git a/bugs/bug0035.pp b/bugs/bug0035.pp new file mode 100644 index 0000000000..7a0748339c --- /dev/null +++ b/bugs/bug0035.pp @@ -0,0 +1,13 @@ +program bug0035; + +{Discovered by Daniel Mantione.} + +label hallo; + +begin + writeln('Hello'); + begin +hallo: {Error message: Incorrect expression.} + end; + writeln('Hello again'); +end. diff --git a/bugs/bug0036.pp b/bugs/bug0036.pp new file mode 100644 index 0000000000..2cba15426c --- /dev/null +++ b/bugs/bug0036.pp @@ -0,0 +1,9 @@ +program bug0036; + +{Discovered by Daniel Mantione.} + +var a:array[0..31] of char; + +begin + a:=' '; {Incorrect Pascal statement, but why a protection error?} +end. diff --git a/bugs/bug0037.pp b/bugs/bug0037.pp new file mode 100644 index 0000000000..830d513463 --- /dev/null +++ b/bugs/bug0037.pp @@ -0,0 +1,17 @@ +uses + graph,crt; + +var + gd,gm : integer; + +begin + gd:=detect; + initgraph(gd,gm,''); + line(1,1,100,100); + readkey; + setgraphmode($107); + line(100,100,1024,800); + readkey; + closegraph; +end. + diff --git a/bugs/bug0038.pp b/bugs/bug0038.pp new file mode 100644 index 0000000000..ce9c4c5809 --- /dev/null +++ b/bugs/bug0038.pp @@ -0,0 +1,5 @@ +CONST ps : ^STRING = nil; + +begin +end. + diff --git a/bugs/bug0039.pp b/bugs/bug0039.pp new file mode 100644 index 0000000000..0e0ca1910d --- /dev/null +++ b/bugs/bug0039.pp @@ -0,0 +1,10 @@ +VAR a : BYTE; +BEGIN + a := 1; + IF a=0 THEN + IF a=1 THEN a:=2 + ELSE + ELSE a:=3; { "Illegal expression" } +END. + + diff --git a/bugs/bug0040.pp b/bugs/bug0040.pp new file mode 100644 index 0000000000..ffb08f984a --- /dev/null +++ b/bugs/bug0040.pp @@ -0,0 +1,26 @@ +{ xor operator bug } +{ needs fix in pass_1.pas line } +{ 706. as well as in the code } +{ generator - secondadd() } +var + b1,b2: boolean; +Begin + b1:=true; + b2:=false; + If (b1 xor b2) Then + begin + end + else + begin + writeln('Problem with bool xor'); + halt; + end; + b1:=true; + b2:=true; + If (b1 xor b2) Then + begin + writeln('Problem with bool xor'); + halt; + end; + writeln('No problem found'); +end. diff --git a/bugs/bug0041.pp b/bugs/bug0041.pp new file mode 100644 index 0000000000..51f617c575 --- /dev/null +++ b/bugs/bug0041.pp @@ -0,0 +1,8 @@ +var + b1: boolean; +Begin + begin + If b1 then { illegal expression } + end; + while b1 do +End. diff --git a/bugs/bug0042.pp b/bugs/bug0042.pp new file mode 100644 index 0000000000..d22e944467 --- /dev/null +++ b/bugs/bug0042.pp @@ -0,0 +1,10 @@ +Program SomeCrash; +{ with pp -TDOS -Rintel bug0042.pp } +{ I'll try to fix this for next release -- Carl } + +Begin + asm + mov ax,3*-4 { evaluator stack underflow } + end; { due to two operators following each other } +end. { this will also happen in att syntax. } + diff --git a/bugs/bug0043.pp b/bugs/bug0043.pp new file mode 100644 index 0000000000..4e42ad408b --- /dev/null +++ b/bugs/bug0043.pp @@ -0,0 +1,32 @@ +{ THE OUTPUT is incorrect but the } +{ parsing is correct. } +{ under nasm output only. } +{ works correctly under tasm/gas } +{ other problems occur with other } +{ things in math.inc } +{ pp -TDOS -Ratt -Anasm bug0043.pp } + procedure frac; + + begin + asm + subl $16,%esp + fnstcw -4(%ebp) + fwait { unknown instruction } + movw -4(%ebp),%cx + orw $0x0c3f,%cx + movw %cx,-8(%ebp) + fldcw -8(%ebp) + fwait { unknown instruction } + fldl 8(%ebp) + frndint + fsubl 8(%ebp) + fabsl + fclex + fldcw -4(%ebp) + leave + ret $8 + end ['ECX']; + end; + +Begin +end. diff --git a/bugs/bug0044.pp b/bugs/bug0044.pp new file mode 100644 index 0000000000..5af309d2ec --- /dev/null +++ b/bugs/bug0044.pp @@ -0,0 +1,16 @@ + { Problem with nested comments -- as you can probably see } + { but it does give out kind of a funny error output :) } + + + {$UNDEF VP} + + {$IFDEF Windows} ssss {$ENDIF} {No Syntax Error} + + {$IFDEF VP} + {$D+}{$R+} + {$ELSE} + {$IFDEF Windows} ssss {$ENDIF} {Syntax Error at: Col 25 } + {$ENDIF} + + BEGIN + END. diff --git a/bugs/bug0045.pp b/bugs/bug0045.pp new file mode 100644 index 0000000000..a76647b7ad --- /dev/null +++ b/bugs/bug0045.pp @@ -0,0 +1,26 @@ + +TYPE + tmyexample =object + public + constructor init; + destructor done; virtual; + private + procedure mytest;virtual; { syntax error --> should give only a +warning ? } + end; + + constructor tmyexample.init; + begin + end; + + destructor tmyexample.done; + Begin + end; + + procedure tmyexample.mytest; + begin + end; + +Begin +end. + diff --git a/bugs/bug0046.pp b/bugs/bug0046.pp new file mode 100644 index 0000000000..b2957d8d71 --- /dev/null +++ b/bugs/bug0046.pp @@ -0,0 +1,43 @@ +program test; + +{$ifdef fpk} +{$ifdef go32v2} +uses + dpmiexcp; +{$endif} +{$endif} + +type byteset = set of byte; + bl = record i,j : longint; + end; +const set1 : byteset = [1,50,220]; + set2 : byteset = [55]; +var i : longint; + b : bl; + + function bi : longint; + + begin + bi:=b.i; + end; + +begin +set1:=set1+set2; +writeln('set 1 = [1,50,55,220]'); +i:=50; +if i in set1 then writeln(i,' is in set1'); +i:=220; +if i in set1 then writeln(i,' is in set1'); +i:=$100+220; +if i in set1 then writeln(i,' is in set1'); +i:=-35; +if i in set1 then writeln(i,' is in set1'); +b.i:=50; +i:=$100+220; +if i in [50,220] then writeln(i,' is in [50,220]'); +if Bi in [50,220] then writeln(b.i,' is in [50,220]'); +b.i:=220; +if bi in [50,220] then writeln(b.i,' is in [50,220]'); +B.i:=-36; +if bi in [50,220] then writeln(B.i,' is in [50,220]'); +end. diff --git a/bugs/bug0047.pp b/bugs/bug0047.pp new file mode 100644 index 0000000000..e00f64c8a1 --- /dev/null +++ b/bugs/bug0047.pp @@ -0,0 +1,13 @@ +procedure test; + + begin + end; + +var + p1 : procedure; + p2 : pointer; + +begin + p1:=@test; + p2:=@test; +end. diff --git a/bugs/bug0048.pp b/bugs/bug0048.pp new file mode 100644 index 0000000000..80129428a4 --- /dev/null +++ b/bugs/bug0048.pp @@ -0,0 +1,26 @@ +uses + graph,crt; + +var + gd,gm : integer; + i,size : longint; + p : pointer; + +begin + gd:=detect; + initgraph(gd,gm,''); + line(0,0,getmaxx,0); + readkey; + size:=imagesize(0,0,getmaxx,0); + getmem(p,size); + getimage(0,0,getmaxx,0,p^); + cleardevice; + for i:=0 to getmaxy do + begin + putimage(0,i,p^,xorput); + putimage(0,i,p^,xorput); + end; + readkey; + closegraph; +end. + diff --git a/bugs/bug0049.pp b/bugs/bug0049.pp new file mode 100644 index 0000000000..1ef2219cb2 --- /dev/null +++ b/bugs/bug0049.pp @@ -0,0 +1,6 @@ +type + days = (Mon,Tue,Wed,Thu,Fri,Sat,Sun); + weekend = Sat..Sun; + +begin +end. diff --git a/bugs/bug0050.pp b/bugs/bug0050.pp new file mode 100644 index 0000000000..6a1a34e864 --- /dev/null +++ b/bugs/bug0050.pp @@ -0,0 +1,9 @@ +function Append : Boolean; + + procedure DoAppend; + begin + Append := true; + end; + +begin +end. diff --git a/bugs/bug0051.pp b/bugs/bug0051.pp new file mode 100644 index 0000000000..d87b92403f --- /dev/null +++ b/bugs/bug0051.pp @@ -0,0 +1,31 @@ +program TestPutP; + +uses crt,graph; + +var gd,gm,gError,yi,i : integer; + col: longint; +BEGIN + gm:=$111; {640x480/64K HiColor} + gd:=$FF; + + InitGraph(gd,gm,''); + gError := graphResult; + IF gError <> grOk + THEN begin + writeln ('graphDriver=',gd,' graphMode=',gm, + #13#10'Graphics error: ',gError); + halt(1); + end; + + for i := 0 to 255 + do begin + col := i shl 16 + (i div 2) shl 8 + (i div 3); + for yi := 0 to 20 do + PutPixel (i,yi,col); + SetColor (col); + Line (i,22,i,42); + end; + readkey; + + closegraph; +END. diff --git a/bugs/bug0053.pp b/bugs/bug0053.pp new file mode 100644 index 0000000000..140159378e --- /dev/null +++ b/bugs/bug0053.pp @@ -0,0 +1,15 @@ +procedure abc(var a : array of char); + + begin + // error: a:='asdf'; + end; + +var + c : array[0..10] of char; + +begin + abc(c); + writeln(c); + // error: writeln(a); +end. + diff --git a/bugs/bug0054.pp b/bugs/bug0054.pp new file mode 100644 index 0000000000..9955d6b31c --- /dev/null +++ b/bugs/bug0054.pp @@ -0,0 +1,6 @@ +var + wb : wordbool; + wl : longbool; + +begin +end. diff --git a/bugs/bug0055.pp b/bugs/bug0055.pp new file mode 100644 index 0000000000..238a996567 --- /dev/null +++ b/bugs/bug0055.pp @@ -0,0 +1,15 @@ +type + tarraysingle = array[0..1] of single; + +procedure test(var a : tarraysingle); + +var + i,j,k : integer; + +begin + a[i]:=a[j]-a[k]; +end; + +begin +end. + diff --git a/bugs/bug0056.pp b/bugs/bug0056.pp new file mode 100644 index 0000000000..cc92e4bb8b --- /dev/null +++ b/bugs/bug0056.pp @@ -0,0 +1,14 @@ +PROGRAM ShowBug; + +(* This will compile +VAR N, E: Integer;*) + +(* This will NOT compile*) +VAR N, E: LongInt; + +BEGIN + E := 2; + WriteLn(E); + N := 44 - E; + WriteLn(N); +END. diff --git a/bugs/bug0057.pp b/bugs/bug0057.pp new file mode 100644 index 0000000000..20f1a8b082 --- /dev/null +++ b/bugs/bug0057.pp @@ -0,0 +1,18 @@ +uses + graph,crt; + +var + gd,gm : integer; + +begin + gd:=detect; + gm:=$103; + initgraph(gd,gm,''); + line(1,1,100,100); + readkey; + closegraph; + initgraph(gd,gm,''); + line(100,100,1,100); + readkey; + closegraph; +end. diff --git a/bugs/bug0058.pp b/bugs/bug0058.pp new file mode 100644 index 0000000000..2b23efaf2a --- /dev/null +++ b/bugs/bug0058.pp @@ -0,0 +1,9 @@ +{$r+} +var + a1 : array[0..1,0..1] of word; + a2 : array[0..1,0..1] of longint; + i,j,l,n : longint; + +begin + a1[i,j]:=a2[l,n]; +end. diff --git a/bugs/bug0059.pp b/bugs/bug0059.pp new file mode 100644 index 0000000000..05a247c2c4 --- /dev/null +++ b/bugs/bug0059.pp @@ -0,0 +1,9 @@ +Program ConstBug; + +Const + S = ord('J'); + t: byte = ord('J'); + + +Begin +end. diff --git a/bugs/bug0060.pp b/bugs/bug0060.pp new file mode 100644 index 0000000000..1986a38fd3 --- /dev/null +++ b/bugs/bug0060.pp @@ -0,0 +1,21 @@ +Program Test; + +{ No errors -- problems is due to the fact that the rules for type +compatibility (p.47 language guide) -- are not respected, in other words +in case statements there is no type checking whatsoever in fpc!! + I think that these are separate cases: + 1st case) s32bit,u32bit,u8bit,s8bit,s16bit,u16bit + 2nd case) uchar + 3rd case) bool8bit +These are not /should not be compatible with each other in a case +statement imho - CEC +} + +var + myvar:char; +Begin + case myvar of + 1: ; + #2: ; + end; +end. diff --git a/bugs/bug0061.pp b/bugs/bug0061.pp new file mode 100644 index 0000000000..1ebb7697c9 --- /dev/null +++ b/bugs/bug0061.pp @@ -0,0 +1,3 @@ +Begin + 55ms; +end. diff --git a/bugs/bug0062.pp b/bugs/bug0062.pp new file mode 100644 index 0000000000..0b729e1fae --- /dev/null +++ b/bugs/bug0062.pp @@ -0,0 +1,9 @@ +Program Bug0062; + + +var + myvar:boolean; +Begin + { by fixing this we also start partly implementing LONGBOOL/WORDBOOL } + myvar:=boolean(1); { illegal type conversion } +end. diff --git a/bugs/bug0063.pp b/bugs/bug0063.pp new file mode 100644 index 0000000000..87a408e62c --- /dev/null +++ b/bugs/bug0063.pp @@ -0,0 +1,13 @@ +{ may also crash/do weird error messages with the compiler } +var + min: char; + max: char; + i: char; +begin + min:='c'; + max:='z'; + if i in [min..max] then + Begin + end; +end. + diff --git a/bugs/bug0064.pp b/bugs/bug0064.pp new file mode 100644 index 0000000000..3fe56fd7dc --- /dev/null +++ b/bugs/bug0064.pp @@ -0,0 +1,15 @@ +var + i: byte; + j: integer; + c: char; +Begin + case i of + Ord('x'): ; + end; + case j of + Ord('x'): ; + end; + case c of + Chr(112): ; + end; +end. \ No newline at end of file diff --git a/bugs/bug0065.pp b/bugs/bug0065.pp new file mode 100644 index 0000000000..58d287aa6d --- /dev/null +++ b/bugs/bug0065.pp @@ -0,0 +1,10 @@ +Program Example27; + +{ Program to demonstrate the Frac function. } + +Var R : Real; + +begin + Writeln (Frac (123.456):0:3); { Prints O.456 } + Writeln (Frac (-123.456):0:3); { Prints -O.456 } +end. diff --git a/bugs/bug0066.pp b/bugs/bug0066.pp new file mode 100644 index 0000000000..bef31138a4 --- /dev/null +++ b/bugs/bug0066.pp @@ -0,0 +1,10 @@ +Program Example54; + +{ Program to demonstrate the Round function. } + +begin + Writeln (Round(123.456)); { Prints 124 } + Writeln (Round(-123.456)); { Prints -124 } + Writeln (Round(12.3456)); { Prints 12 } + Writeln (Round(-12.3456)); { Prints -12 } +end. diff --git a/bugs/bug0067.pp b/bugs/bug0067.pp new file mode 100644 index 0000000000..198d054f3a --- /dev/null +++ b/bugs/bug0067.pp @@ -0,0 +1,18 @@ +unit bug0067; + +interface + +type + tlong=record + a : longint; + end; + +procedure p(var t:tlong); + +implementation + +procedure p(var t:tlong); +begin +end; + +end. diff --git a/bugs/bug0067b.pp b/bugs/bug0067b.pp new file mode 100644 index 0000000000..70a0e80e08 --- /dev/null +++ b/bugs/bug0067b.pp @@ -0,0 +1,27 @@ +unit bug0067b; + +interface + + +type + tlong=record + a : longint; + end; + +procedure p(var l:tlong); + +implementation + +uses bug0067; + +{ the tlong parameter is taken from unit bug0067, + and not from the interface part of this unit. + setting the uses clause in the interface part + removes the problem } + +procedure p(var l:tlong); +begin + bug0067.p(bug0067.tlong(l)); +end; + +end. diff --git a/bugs/bug0068.pp b/bugs/bug0068.pp new file mode 100644 index 0000000000..a668880ddf --- /dev/null +++ b/bugs/bug0068.pp @@ -0,0 +1,9 @@ +program bug0068; + +var + p : pointer; + l : longint; +begin + l:=Ofs(p); { Ofs returns a pointer type !? } + +end. diff --git a/bugs/bug0069.pp b/bugs/bug0069.pp new file mode 100644 index 0000000000..73c45c41b8 --- /dev/null +++ b/bugs/bug0069.pp @@ -0,0 +1,25 @@ +Unit bug0068; + +Interface + +Procedure MyTest;Far; { IMPLEMENTATION expected error. } + +{ Further information: NEAR IS NOT ALLOWED IN BORLAND PASCAL } +{ Therefore the bugfix should only be for the FAR keyword. } +(* Procedure MySecondTest;Near; *) + +Implementation + +{ near and far are not allowed here, but maybe we don't care since they are ignored by } +{ FPC. } +Procedure MyTest; +Begin +end; + +Procedure MySecondTest; +Begin +end; + + + +end. diff --git a/bugs/bug0070.pp b/bugs/bug0070.pp new file mode 100644 index 0000000000..aa6044669f --- /dev/null +++ b/bugs/bug0070.pp @@ -0,0 +1,10 @@ +Program Test; + +type + myenum = (YES,NO,MAYBE); +var + myvar:set of myenum; +Begin + Include(myvar,Yes); + Exclude(myvar,No); +end. diff --git a/bugs/bug0071.pp b/bugs/bug0071.pp new file mode 100644 index 0000000000..679f9eaf17 --- /dev/null +++ b/bugs/bug0071.pp @@ -0,0 +1,5 @@ +program bug71; + +begin + writeln (' +end. \ No newline at end of file diff --git a/bugs/bug0072.pp b/bugs/bug0072.pp new file mode 100644 index 0000000000..238a996567 --- /dev/null +++ b/bugs/bug0072.pp @@ -0,0 +1,15 @@ +type + tarraysingle = array[0..1] of single; + +procedure test(var a : tarraysingle); + +var + i,j,k : integer; + +begin + a[i]:=a[j]-a[k]; +end; + +begin +end. + diff --git a/bugs/bug0073.pp b/bugs/bug0073.pp new file mode 100644 index 0000000000..e0f2626044 --- /dev/null +++ b/bugs/bug0073.pp @@ -0,0 +1,30 @@ +Unit bug0068; + +Interface + + +Procedure MyTest;Far; { IMPLEMENTATION expected error. } + +{ Further information: NEAR IS NOT ALLOWED IN BORLAND PASCAL } +{ Therefore the bugfix should only be for the FAR keyword. } + Procedure MySecondTest; + +Implementation + +{ near and far are not allowed here, but maybe we don't care since they are ignored by } +{ FPC. } +Procedure MyTest; +Begin +end; + + + +Procedure MySecondTest;Far; +Begin +end; + + + + + +end. diff --git a/bugs/bug0074.pp b/bugs/bug0074.pp new file mode 100644 index 0000000000..a6683509da --- /dev/null +++ b/bugs/bug0074.pp @@ -0,0 +1,28 @@ +type + tmyobject = object + constructor init; + procedure callit; virtual; + destructor done; virtual; + end; + + + constructor tmyobject.init; + Begin + end; + + destructor tmyobject.done; + Begin + end; + + procedure tmyobject.callit; + Begin + WriteLn('Hello...'); + end; + + var + obj: tmyobject; + Begin + obj.init; + obj.callit; +{ obj.done;} + end. diff --git a/bugs/bug0075.pp b/bugs/bug0075.pp new file mode 100644 index 0000000000..4820a8022c --- /dev/null +++ b/bugs/bug0075.pp @@ -0,0 +1,31 @@ +Unit bug0068; + +Interface + + +Procedure MyTest;Far; { IMPLEMENTATION expected error. } + +{ Further information: NEAR IS NOT ALLOWED IN BORLAND PASCAL } +{ Therefore the bugfix should only be for the FAR keyword. } + Procedure MySecondTest; + +Implementation + +{ near and far are not allowed here, but maybe we don't care since they are ignored by } +{ FPC. } +Procedure MyTest; +Begin +end; + +Procedure MySecondTest;Far;Forward; + + +Procedure MySecondTest;Far; +Begin +end; + + + + + +end. diff --git a/bugs/bug0076.pp b/bugs/bug0076.pp new file mode 100644 index 0000000000..bded18ade7 --- /dev/null +++ b/bugs/bug0076.pp @@ -0,0 +1,24 @@ +program bug0076; + +{Generates wrong code when compiled with output set to intel asm. + + Reported from mailinglist by Vtech Kavan. + + 15 Januari 1998, Daniel Mantione} + +type TVtx2D = record x,y:longint end; + +var Vtx2d:array[0..2] of TVtx2D; + +function SetupScanLines(va,vb,vc:word):single; +var dx3d,dx2d,dy2d,dz,ex3d,ex2d,ez:longint; + r:single; +begin + dy2d := Vtx2d[vb].y; + r := (dy2d-Vtx2d[va].y); {this line causes error!!!!!!!!!!!!!!!!!!!} +end; + +begin + SetupScanLines(1,2,3); +end. + diff --git a/bugs/bug0077.pp b/bugs/bug0077.pp new file mode 100644 index 0000000000..c5f69f60ed --- /dev/null +++ b/bugs/bug0077.pp @@ -0,0 +1,9 @@ +uses + bug0077b; + +begin + b:=89; + writeln(a); +end. + + diff --git a/bugs/bug0077b.pp b/bugs/bug0077b.pp new file mode 100644 index 0000000000..6ba5988027 --- /dev/null +++ b/bugs/bug0077b.pp @@ -0,0 +1,11 @@ +unit bug0077b; + + interface + + var + a : longint; + b : longint absolute a; + + implementation + +end. diff --git a/bugs/bug0078.pp b/bugs/bug0078.pp new file mode 100644 index 0000000000..9c803b053c --- /dev/null +++ b/bugs/bug0078.pp @@ -0,0 +1,7 @@ +{ shows error with asm_size_mismatch } +Begin + asm + mov eax, 2147483647 + mov eax, 2000000000 + end; +end. diff --git a/bugs/bug0079.pp b/bugs/bug0079.pp new file mode 100644 index 0000000000..47e8c408a1 --- /dev/null +++ b/bugs/bug0079.pp @@ -0,0 +1,18 @@ + +procedure nothing(x,y: longint);assembler; +asm + mov eax,x + mov ebx,y +end; + + +{procedure nothing(x,y: longint); +begin + asm + mov eax,x + mov ebx,y + end; +end; } + +Begin +end. diff --git a/bugs/bug0080.pp b/bugs/bug0080.pp new file mode 100644 index 0000000000..e4258a4c0e --- /dev/null +++ b/bugs/bug0080.pp @@ -0,0 +1,8 @@ +program bug0080; + +type + + tHugeArray = array [ 1 .. High(Word) ] of byte; + +begin +end. \ No newline at end of file diff --git a/bugs/bug0081.pp b/bugs/bug0081.pp new file mode 100644 index 0000000000..f0762f8eb1 --- /dev/null +++ b/bugs/bug0081.pp @@ -0,0 +1,7 @@ +program bug0081; + +const + EOL : array [1..2] of char = #13 + #10; + +begin +end. diff --git a/bugs/bug0082.pp b/bugs/bug0082.pp new file mode 100644 index 0000000000..2164ed1a71 --- /dev/null +++ b/bugs/bug0082.pp @@ -0,0 +1,29 @@ +Unit bug0083; + +interface + +Type T = OBject + Constructor Init; + Destructor Free; virtual; + Destructor Destroy; virtual; + end; + +implementation + +constructor T.INit; + +begin +end; + +Destructor t.Free; + +begin +end; + +Destructor t.Destroy; + +begin +end; + + +end. \ No newline at end of file diff --git a/bugs/bug0084.pp b/bugs/bug0084.pp new file mode 100644 index 0000000000..ed1848fc1f --- /dev/null +++ b/bugs/bug0084.pp @@ -0,0 +1,13 @@ + +{ Basic Pascal principles gone done the drain... !!!! } +var + v: word; + w: shortint; + z: byte; + y: integer; +Begin + y:=64000; + z:=32767; + w:=64000; + v:=-1; +end. diff --git a/bugs/bug0085.pp b/bugs/bug0085.pp new file mode 100644 index 0000000000..432ee2d0f2 --- /dev/null +++ b/bugs/bug0085.pp @@ -0,0 +1,3 @@ +Begin + writeln(l); +end. diff --git a/bugs/bug0086.pp b/bugs/bug0086.pp new file mode 100644 index 0000000000..31d584af7b --- /dev/null +++ b/bugs/bug0086.pp @@ -0,0 +1,15 @@ + +var + v: word; + w: shortint; + z: byte; + y: integer; + +type + zz: shortint = 255; +Begin + y:=64000; + z:=32767; + w:=64000; + v:=-1; +end. diff --git a/bugs/bug0087.pp b/bugs/bug0087.pp new file mode 100644 index 0000000000..fafea37497 --- /dev/null +++ b/bugs/bug0087.pp @@ -0,0 +1,15 @@ +{ + BP Error message is 'Pointer variable Expected' +} +type + tobj=object + l : longint; + constructor init; + end; +var + o : tobj; +begin + new(o); {This will create a internal error 9999} + new(o,init); {This will create a Segfault and Core Dump under linux} +end. + \ No newline at end of file diff --git a/bugs/bug0088.pp b/bugs/bug0088.pp new file mode 100644 index 0000000000..194a7c08a2 --- /dev/null +++ b/bugs/bug0088.pp @@ -0,0 +1,3 @@ +Begin + typeof(x1); { Gives out an internal error -- better then 9999 though } +end. diff --git a/bugs/bug0089.pp b/bugs/bug0089.pp new file mode 100644 index 0000000000..3dad168655 --- /dev/null +++ b/bugs/bug0089.pp @@ -0,0 +1,3 @@ +Begin + sizeof(x); +end. diff --git a/bugs/bug0090.pp b/bugs/bug0090.pp new file mode 100644 index 0000000000..aa05feedd6 --- /dev/null +++ b/bugs/bug0090.pp @@ -0,0 +1,9 @@ +{$X+} +var + mystr : array[0..3] of char; + +Begin + if mystr = #0#0#0#0 then + Begin + end; +end. diff --git a/bugs/bug0091.pp b/bugs/bug0091.pp new file mode 100644 index 0000000000..26acf31cc5 --- /dev/null +++ b/bugs/bug0091.pp @@ -0,0 +1,23 @@ +{ Page 22 of The Language Guide of Turbo Pascal } +var + t: byte; +const + a = Trunc(1.3); + b = Round(1.6); + c = abs(-5); + ErrStr = 'Hello!'; + d = Length(ErrStr); + e = Lo($1234); + f = Hi($1234); + g = Chr(34); + h = Odd(1); + i = Ord('3'); + j = Pred(34); + l = Sizeof(t); + m = Succ(9); + n = Swap($1234); + o = ptr(0,0); +Begin +end. + + diff --git a/bugs/bug0092.pp b/bugs/bug0092.pp new file mode 100644 index 0000000000..f6b253f1df --- /dev/null +++ b/bugs/bug0092.pp @@ -0,0 +1,11 @@ +program bug; + +{The unfixable bug. Maybe we get an idea when we keep looking at it. + + Daniel Mantione 5 februari 1998.} + +var a:1..4=2; {Crash 1.} + b:set of 1..4=[2,3]; {Also crashes, but is the same bug.} + +begin +end. diff --git a/bugs/bug0093.pp b/bugs/bug0093.pp new file mode 100644 index 0000000000..7faf66927f --- /dev/null +++ b/bugs/bug0093.pp @@ -0,0 +1,18 @@ +{ Two cardinal type bugs } +var + c : cardinal; + l : longint; + b : byte; + s : shortint; + w : word; +begin + b:=123; + w:=s; + l:=b; + c:=b; {generates movzbl %eax,%edx instead of movzbl %al,%edx} + + c:=123; + writeln(c); {Shows '0' outline right! instead of '123' outlined left} + c:=$7fffffff; + writeln(c); {Shows '0' outline right! instead of '123' outlined left} +end. diff --git a/bugs/bug0094.pp b/bugs/bug0094.pp new file mode 100644 index 0000000000..6457802a25 --- /dev/null +++ b/bugs/bug0094.pp @@ -0,0 +1,5 @@ +begin + case textrec(l).mode of + 1 ; + end; +end. \ No newline at end of file diff --git a/bugs/bug0095.pp b/bugs/bug0095.pp new file mode 100644 index 0000000000..5ddfd435bd --- /dev/null +++ b/bugs/bug0095.pp @@ -0,0 +1,15 @@ +var + ch : char; +begin + ch:=#3; + case ch of + #0..#31 : ; + else + writeln('bug'); + end; + case ch of + #0,#1,#3 : ; + else + writeln('bug'); + end; +end. diff --git a/bugs/bug0096.pp b/bugs/bug0096.pp new file mode 100644 index 0000000000..fc8051cd4b --- /dev/null +++ b/bugs/bug0096.pp @@ -0,0 +1,24 @@ +type + TParent = object + end; + + PParent = ^TParent; + + TChild = object(TParent) + end; + +procedure aProc(const x : TParent ); +begin +end; + +procedure anotherProc(var x : TParent ); +begin +end; + +var + y : TChild; + + begin + aProc(y); + anotherProc(y); + end. diff --git a/bugs/bug0097.pp b/bugs/bug0097.pp new file mode 100644 index 0000000000..0f3623b296 --- /dev/null +++ b/bugs/bug0097.pp @@ -0,0 +1,19 @@ +{ + This compiles fine with FPC, but not with Bp7 see 2 comments +} + +type + t=object + s : string { No ; needed ? } + procedure p; + end; + +procedure t.p; +var + s : longint; { Not allowed with BP7 } +begin +end; + + +begin +end. diff --git a/bugs/bug0098.pp b/bugs/bug0098.pp new file mode 100644 index 0000000000..9b57eed223 --- /dev/null +++ b/bugs/bug0098.pp @@ -0,0 +1,45 @@ +program Test; +{ Show how to seek to an OFFSET (not a line number) in a textfile, } +{ without using asm. Arne de Bruijn, 1994, PD } +uses Dos; { For TextRec and FileRec } +var + F:text; + L:longint; + S:string; +begin + assign(F,'TEST.PAS'); { Assign F to itself } + reset(F); { Open it (as a textfile) } + ReadLn(F); { Just read some lines } + ReadLn(F); + ReadLn(F); + FileRec((@F)^).Mode:=fmInOut; { Set to binary mode } + { (The (@F)^ part is to let TP 'forget' the type of the structure, so } + { you can type-caste it to everything (note that with and without (@X)^ } + { can give a different value, longint(bytevar) gives the same value as } + { bytevar, while longint((@bytevar)^) gives the same as } + { longint absolute Bytevar (i.e. all 4 bytes in a longint are readed } + { from memory instead of 3 filled with zeros))) } + FileRec((@F)^).RecSize:=1; { Set record size to 1 (a byte)} + L:=(FilePos(File((@F)^))-TextRec(F).BufEnd)+TextRec(F).BufPos; +{... This line didn't work the last time I tried, it chokes on the "File" +typecasting thing.} + + { Get the fileposition, subtract the already readed buffer, and add the } + { position in that buffer } + TextRec(F).Mode:=fmInput; { Set back to text mode } + TextRec(F).BufSize:=SizeOf(TextBuf); { BufSize overwritten by RecSize } + { Doesn't work with SetTextBuf! } + ReadLn(F,S); { Read the next line } + WriteLn('Next line:',S); { Display it } + FileRec((@F)^).Mode:=fmInOut; { Set to binary mode } + FileRec((@F)^).RecSize:=1; { Set record size to 1 (a byte)} + Seek(File((@F)^),L); { Do the seek } +{... And again here.} + + TextRec(F).Mode:=fmInput; { Set back to text mode } + TextRec(F).BufSize:=SizeOf(TextBuf); { Doesn't work with SetTextBuf! } + TextRec(F).BufPos:=0; TextRec(F).BufEnd:=0; { Reset buffer counters } + ReadLn(F,S); { Show that it worked, the same } + WriteLn('That line again:',S); { line readed again! } + Close(F); { Close it } +end. diff --git a/bugs/bug0099.pp b/bugs/bug0099.pp new file mode 100644 index 0000000000..ef8dc501af --- /dev/null +++ b/bugs/bug0099.pp @@ -0,0 +1,7 @@ + +{$R+} +var w:word; + s:Shortint; +begin + w := s; +end. diff --git a/bugs/bug0100.pp b/bugs/bug0100.pp new file mode 100644 index 0000000000..13ff576b30 --- /dev/null +++ b/bugs/bug0100.pp @@ -0,0 +1,7 @@ +unit u; +interface +uses dos; +implementation +uses dos; { Not Allowed in BP7} +end. + diff --git a/bugs/bug0101.pp b/bugs/bug0101.pp new file mode 100644 index 0000000000..ff911e2201 --- /dev/null +++ b/bugs/bug0101.pp @@ -0,0 +1,18 @@ +Unit XYZ; + +Interface + + Procedure MyProc(V: Integer); + + +Implementation + + Procedure MyProc(Y: Integer); + Begin + end; + + +end. + + + diff --git a/bugs/bug0102.pp b/bugs/bug0102.pp new file mode 100644 index 0000000000..f503486a60 --- /dev/null +++ b/bugs/bug0102.pp @@ -0,0 +1,16 @@ + +unit bug0102; + interface + + implementation + + procedure int_help_constructor; + + begin + asm + movem.l d0-a7,-(sp) + end; + end; + + + end. diff --git a/bugs/bug0103.pp b/bugs/bug0103.pp new file mode 100644 index 0000000000..d8eb8ecdbf --- /dev/null +++ b/bugs/bug0103.pp @@ -0,0 +1,8 @@ + +Var + out: boolean; + int: byte; +Begin + { savesize is different! } + out:=boolean((int AND $20) SHL 4); +end. diff --git a/bugs/bug0104.pp b/bugs/bug0104.pp new file mode 100644 index 0000000000..c8745548e8 --- /dev/null +++ b/bugs/bug0104.pp @@ -0,0 +1,13 @@ +uses + dpmiexcp; +{ Two cardinal type bugs } +var + c : cardinal; +begin + c:=$80000000; + writeln(c); + c:=$80001234; + writeln(c); + c:=$ffffffff; + writeln(c); +end. diff --git a/bugs/bug0105.pp b/bugs/bug0105.pp new file mode 100644 index 0000000000..b609aa82a2 --- /dev/null +++ b/bugs/bug0105.pp @@ -0,0 +1,15 @@ +{$R+} +{ BOUND check error... I don't think this is a code generator error } +{ but an error because the type casting is not considered at all! } +{ Must be compiled with -Cr } + + +Var + Sel: Word; + v: longint; +Begin + v:=$00ffffff; + Sel:=word(v); + writeln(sel); + sel:=v; +end. diff --git a/bugs/bug0106.pp b/bugs/bug0106.pp new file mode 100644 index 0000000000..9d2a26f93f --- /dev/null +++ b/bugs/bug0106.pp @@ -0,0 +1,11 @@ + +{ I think this now occurs with most type casting... } +{ I think type casting is no longer considered?? } + +Var + Sel: Word; + Sel2: byte; +Begin + Sel:=word($7fffffff); + Sel2:=byte($7fff); +end. diff --git a/bugs/bug0107.pp b/bugs/bug0107.pp new file mode 100644 index 0000000000..b4d0644a7d --- /dev/null +++ b/bugs/bug0107.pp @@ -0,0 +1,28 @@ +{ PAGE FAULT PROBLEM ... TEST UNDER DOS ONLY! Not windows... } +{ -Cr -g flags } + +Program Test1; + +uses + dpmiexcp; +type + myObject = object + constructor init; + procedure v;virtual; + end; + + constructor myobject.init; + Begin + end; + + procedure myobject.v; + Begin + WriteLn('Hello....'); + end; + +var + my: myobject; +Begin + my.init; + my.v; +end. diff --git a/bugs/bug0108.pp b/bugs/bug0108.pp new file mode 100644 index 0000000000..e3e3fec454 --- /dev/null +++ b/bugs/bug0108.pp @@ -0,0 +1,5 @@ +uses + dos, + ; +begin +end. \ No newline at end of file diff --git a/bugs/bug0109.pp b/bugs/bug0109.pp new file mode 100644 index 0000000000..dac689d5c7 --- /dev/null +++ b/bugs/bug0109.pp @@ -0,0 +1,9 @@ +Type T = (aa,bb,cc,dd,ee,ff,gg,hh); + Tset = set of t; + +Var a: Tset; + +Begin + If (aa in a^) Then begin end; + {it seems that correct code is generated, but the syntax is wrong} +End. diff --git a/bugs/bug0110.pp b/bugs/bug0110.pp new file mode 100644 index 0000000000..0d6226640c --- /dev/null +++ b/bugs/bug0110.pp @@ -0,0 +1,7 @@ +uses aasm; + +Begin + Case Pai(hp1)^.typ Of + ait_instruction: + End +End. diff --git a/bugs/bug0111.pp b/bugs/bug0111.pp new file mode 100644 index 0000000000..f9286a358c --- /dev/null +++ b/bugs/bug0111.pp @@ -0,0 +1,13 @@ +var + f : file of word; + i : word; + buf : string; +begin + assign(f,'test'); + reset(f); + blockread(f,buf[1],sizeof(buf),i); { This is not allowed in BP7 } + buf[0]:=chr(i); + close(f); + writeln(i); + writeln(buf); +end. \ No newline at end of file diff --git a/bugs/bug0112.pp b/bugs/bug0112.pp new file mode 100644 index 0000000000..e297a5b5b4 --- /dev/null +++ b/bugs/bug0112.pp @@ -0,0 +1,21 @@ +type + TextBuf=array[0..127] of char; + TextRec=record + BufPtr : ^textbuf; + BufPos : word; + end; + +Function ReadNumeric(var f:TextRec;var s:string;base:longint):Boolean; +{ + Read Numeric Input, if buffer is empty then return True +} +begin + while ((base>=10) and (f.BufPtr^[f.BufPos] in ['0'..'9'])) or + ((base=16) and (f.BufPtr^[f.BufPos] in ['A'..'F'])) or + ((base=2) and (f.BufPtr^[f.BufPos] in ['0'..'1'])) do + Begin + End; +end; + +begin +end. diff --git a/bugs/bug0113.pp b/bugs/bug0113.pp new file mode 100644 index 0000000000..05ebf08e65 --- /dev/null +++ b/bugs/bug0113.pp @@ -0,0 +1,13 @@ +program test; + +type pRecord = ^aRecord; + aRecord = record + next : pRecord; + a, b, c : integer; + end; + +const rec1 : aRecord = (next : nil; a : 10; b : 20; c : 30); + rec2 : aRecord = (next : @rec1; a : 20; b : 30; c : 40); + +begin +end. diff --git a/bugs/bug0114.pp b/bugs/bug0114.pp new file mode 100644 index 0000000000..534d6c6a1c --- /dev/null +++ b/bugs/bug0114.pp @@ -0,0 +1,3 @@ +begin + write{ln}(0.997:0:2); +end. diff --git a/bugs/bug0115.pp b/bugs/bug0115.pp new file mode 100644 index 0000000000..4e67896299 --- /dev/null +++ b/bugs/bug0115.pp @@ -0,0 +1,8 @@ +var + c : comp; + +begin + writeln(c); + readln(c); +end. + diff --git a/bugs/bug0116.pp b/bugs/bug0116.pp new file mode 100644 index 0000000000..478aaf4f33 --- /dev/null +++ b/bugs/bug0116.pp @@ -0,0 +1,9 @@ +Procedure test; +{compile with -Og to show bug} + +Var a: Array[1..4000000] of longint; +Begin +End; + +Begin +End. diff --git a/bugs/readme.txt b/bugs/readme.txt new file mode 100644 index 0000000000..11462a0363 --- /dev/null +++ b/bugs/readme.txt @@ -0,0 +1,163 @@ +This directory contains test files for various FPC bugs. +The most files are very simple and it's neccessary to check the assembler +output. + +The first coloumn contains the file name. If the file name is indended, +the bug is fixed and the last coloumn contains the version where +the bug is fixed. + +In future, please add also your name short cut, when fixing a bug. + +Fixed bugs: +----------- + + bug0001.pp tests a bug in the .ascii output (#0 and too long) OK 0.9.2 + bug0002.pp tests for the endless bug in the optimizer OK 0.9.2 + bug0003.pp dito OK 0.9.2 + bug0004.pp tests the continue instruction in the for loop OK 0.9.2 + bug0005.pp tests the if 1=1 then ... bug OK 0.9.2 + bug0006.pp tests the wrong floating point code generation OK 0.9.2 + bug0007.pp tests the infinity loop when using byte counter OK 0.9.2 + bug0008.pp tests the crash when decrementing constants OK 0.9.2 + bug0009.pp tests comperations in function calls a(c<0); OK 0.9.2 + bug0010.pp tests string constants exceeding lines OK 0.9.2 + bug0011.pp tests div/mod bug, where edx is scrambled, if + a called procedure does a div/mod OK 0.9.2 + bug0012.pp tests type conversation byte(a>b) OK 0.9.9 (FK) + bug0015.pp tests for wrong allocated register for return result + of floating function (allocates int register) OK 0.9.2 + bug0018.pp tests for the possibility to declare all types + using pointers "forward" : type p = ^x; x=byte; OK 0.9.3 + bug0021.pp tests compatibility of empty sets with other set + and the evalution of constant sets OK 0.9.3 + bug0022.pp tests getting the address of a method OK 0.9.3 + bug0023.pp tests handling of self pointer in nested methods OK 0.9.3 + + bug0025.pp tests for a wrong uninit. var. warning OK 0.9.3 + bug0026.pp tests for a wrong unused. var. warning OK 0.9.4 + bug0027.pp tests + type + enumtype = (One, two, three, forty:=40, fifty); OK 0.9.5 + bug0028.pp type enumtype = (a); writeln(ord(a)); + bug0029.pp tests typeof(object type) OK 0.99.1 (FK) + bug0030.pp tests type conversations in typed consts OK 0.9.6 + bug0031.pp tests array[boolean] of .... OK 0.9.8 + bug0032.pp tests for a bug with the stack OK 0.9.9 + bug0033.pp tests var p : pchar; begin p:='c'; end. OK 0.9.9 + bug0034.pp shows wrong line numbering when asmbler is parsed OK 0.9.9 + in direct mode. + bug0035.pp label at end of block gives error OK 0.9.9 (FK) + bug0036.pp assigning a single character to array of char ?OK 0.9.9 + gives a protection error + --------- cgi386.pas gives out gpf's when compiling the system OK 0.9.9 (FK) + unit. + bug0037.pp tests missing graph.setgraphmode OK RTL (FK) + bug0038.pp tests const ps : ^string = nil; OK 0.9.9 (FK) + bug0039.pp shows the else-else problem OK 0.9.9 (FK) + bug0040.pp shows the if b1 xor b2 problem where b1,b2 :boolean OK 0.9.9 (FK) + bug0041.pp shows the if then end. problem OK 0.9.9 (FK) + bug0044.pp shows $ifdef and comment nesting/directive problem OK 0.99.1 (PFV) + bug0045.pp shows problem with virtual private methods OK 0.9.9 (FK) + (might not be a true bug but more of an incompatiblity?) + the compiler warns now if there is a private and virtual + method + bug0046.pp problems with sets with values over 128 due to OK 0.99.1 (FK) + sign extension + (already fixed ) but also for SET_IN_BYTE + bug0047.pp compiling with -So crashes the compiler OK 0.99.1 (CEC) + bug0053.pp shows a problem with open arrays OK 0.99.1 (FK) + (crashes a win95-DOS box :) ) + bug0055.pp internal error 10 (means too few registers OK 0.99.1 (FK) + - i386 ONLY) + bug0056.pp shows a _very_ simple expression which generates OK 0.99.1 (FK) + wrong assembler + bug0058.pp causes an internal error 10 (problem with getregisterOK 0.99.1 (FK) + in secondsmaller - i386 ONLY) + bug0059.pp shows the problem with syntax error with ordinal OK 0.99.1 (FK) + constants + bug0060.pp shows missing type checking for case statements OK 0.99.1 (CEC) + bug0061.pp shows wrong errors when compiling (NOT A BUG) OK 0.99.1 + bug0064.pp shows other types of problems with case statements OK 0.99.1 (FK) + bug0065.pp shows that frac() doesn't work correctly. OK 0.99.1 (PFV) + bug0066.pp shows that Round doesn't work correctly. (NOT A BUG) OK 0.99.1 + bug0067.pp and bug0067b.pp (Work together) OK 0.99.1 + Shows incorrect symbol resolution when using uses in implementation + More info can be found in file bug0067b.pp. + bug0068.pp Shows incorrect type of ofs() OK 0.99.1 (PFV and FK) + bug0069.pp Shows problem with far qualifier in units OK 0.99.1 (CEC) + bug0071.pp shows that an unterminated constant string in a OK 0.99.1 (PFV) + writeln() statement crashes the compiler. + bug0072.pp causes an internal error 10 ( i386 ONLY ) OK 0.99.1 (FK) + bug0074.pp shows MAJOR bug when trying to compile valid code OK 0.99.1 (PM/CEC) + bug0075.pp shows invalid pchar output to console OK 0.99.1 + ---------- compiling pp -Us -di386 -Sg system.pp gives GPF OK 0.99.1 + bug0076.pp Bug in intel asm generator. was already fixed OK 0.99.1 (FK) + bug0077.pp shows a bug with absolute in interface part of unit OK 0.99.1 (FK) + bug0077b.pp used by unit bug0077.pp + bug0078.pp Shows problems with longint constant in intel asm OK 0.99.1 (CEC) + parsers + bug0079.pp Shows problems with stackframe with assembler keyword OK 0.99.1 (CEC) + bug0081.pp Shows incompatibility with borland's 'array of char'. OK 0.99.1 (FK) + bug0082.pp Shows incompatibility with BP : Multiple destructors. OK 0.99.1 (FK) + bug0084.pp no more pascal type checking OK 0.99.1 (FK) + bug0085.pp shows runerror 216 OK 0.99.1 (CEC) + bug0086.pp shows runerror 216 OK 0.99.1 (CEC) + bug0087.pp shows internal error 12 - no more SegFaults OK 0.99.1 (FK) + bug0088.pp internal error 12 or Runerror 216 OK 0.99.1 (FK) + bug0089.pp internal error 12 or Runerror 216 OK 0.99.1 (FK) + bug0093.pp Two Cardinal type bugs 0K 0.99.1 (FK/MvC) + bug0094.pp internal error when recordtype not found with case OK 0.99.1 + bug0095.pp case with ranges starting with #0 bugs OK 0.99.1 (FK) + bug0098.pp File type casts are not allowed (works in TP7) OK 0.99.1 (FK) + bug0099.pp wrong assembler code is genereatoed for range check OK 0.99.1 (?) + (at least under 0.99.0) + bug0101.pp no type checking for routines in interfance and OK 0.99.1 (CEC) + implementation + bug0104.pp cardinal greater than $7fffffff aren't written OK 0.99.1 (FK) + correct + bug0105.pp typecasts are now ignored problem (NOT A BUG) OK 0.99.1 + bug0106.pp typecasts are now ignored problem (NOT A BUG) OK 0.99.1 + bug0108.pp gives wrong error message OK 0.99.1 (PFV) + bug0109.pp syntax error not detected when using a set as pointer OK 0.99.1 (FK) + bug0112.pp still generates an internal error 10 OK 0.99.1 (FK) + bug0114.pp writeln problem (by Pavel Ozerski) OK 0.99.1 (PFV) + bug0116.pp when local variable size is > $ffff, enter can't be OK 0.99.1 (FK) + used to create the stack frame, but it is with -Og + +Unproducable bugs: +------------------ + +Unfixed bugs: +------------- +bug0042.pp shows assembler double operator expression problem +bug0043.pp shows assembler nasm output with fpu opcodes problem +bug0048.pp shows a problem with putimage on some computers + (I can't reproduce the bug neither with a Millenium II + nor a Trio64 card (FK) ) +bug0049.pp shows an error while defining subrange types +bug0050.pp can't set a function result in a nested + procedure of a function +bug0051.pp shows a problem with putpixel +bug0052.pp collects missing graph unit routines +bug0054.pp wordbool and longbool types are missed +bug0057.pp shows a crash with switch graph/text/graph +bug0062.pp shows illegal type conversion for boolean +bug0063.pp shows problem with ranges in sets for variables +bug0070.pp shows missing include and exclude from rtl + (probably requires inlining) +bug0073.pp shows incompatiblity with bp for distance qualifiers +bug0080.pp Shows Missing High() (internal) function. +bug0083.pp shows missing "dynamic" set constructor +bug0090.pp shows PChar comparison problem +bug0091.pp missing standard functions in constant expressions +bug0092.pp The unfixable bug. Maybe we find a solution one day. +bug0096.pp problem with objects as parameters +bug0097.pp two errors in bp7 but not in FPC +bug0100.pp a unit may only occure once in uses +bug0102.pp page fault when trying to compile under ppcm68k (intel version) +bug0103.pp problems with boolean typecasts (other type) +bug0107.pp shows page fault problem (run in TRUE DOS mode) +bug0110.pp SigSegv when using undeclared var in Case +bug0111.pp blockread(typedfile,...) is not allowed in TP7 +bug0113.pp point initialization problems +bug0115.pp missing writeln for comp data type diff --git a/docs/.log b/docs/.log new file mode 100644 index 0000000000..856c54264b --- /dev/null +++ b/docs/.log @@ -0,0 +1,35 @@ +This is TeX, Version 3.14159 (C version 6.1) (format=latex 97.10.1) 24 MAR 1998 16:24 +**prog.dvi +(/usr/local/teTeX/texmf/tex/latex/tools/.tex +LaTeX2e <1997/06/01> +Babel and hyphenation patterns for english, french, dutch, loaded. +File ignored) +*x + +! LaTeX Error: Missing \begin{document}. + +See the LaTeX manual or LaTeX Companion for explanation. +Type H for immediate help. + ... + +<*> x + +? +! Emergency stop. + ... + +<*> x + +You're in trouble here. Try typing to proceed. +If that doesn't work, type X to quit. + + +Here is how much of TeX's memory you used: + 7 strings out of 10907 + 198 string characters out of 72268 + 42625 words of memory out of 262141 + 2987 multiletter control sequences out of 9500 + 3956 words of font info for 14 fonts, out of 150000 for 255 + 0 hyphenation exceptions out of 607 + 5i,0n,4p,83b,14s stack positions out of 300i,40n,60p,3000b,4000s +No pages of output. diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000..a2bf105f5d --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,205 @@ +####################################################################### +# Makefile for FPK-Pascal documentation. +# Michael Van Canneyt +####################################################################### +# +# Where do you want the html files to be put ? +DOCINSTALLDIR=/usr/doc/ppc-0.99.0 + +# +# Program definitions +# + +# Latex +ifndef LATEX +LATEX = latex +endif + +# Latex2html conversion. +ifndef LATEX2HTML +LATEX2HTML = latex2html +endif + +# Options for converter +ifndef LATEX2HTMLOPTS +LATEX2HTMLOPTS = -ascii_mode -no_reuse -up_url "../fpctoc.html"\ + -up_title "Free Pascal manuals" -contents_in_navigation\ + -html_version 3.0 +endif + +# DVI to PS converter +ifndef DVIPS +DVIPS=dvips +endif + +# DVI to TXT converter +ifndef DVITXT +DVITXT=dvi2tty -w132 +endif + +# PDF converter +ifndef PDFLATEX +PDFLATEX=pdflatex +endif + +# Makeindex programma +ifndef MAKEINDEX +MAKEINDEX=makeindex +endif + +# + +####################################################################### +# End of configurable section. Do not edit after this line. +####################################################################### + +HTML = user units ref prog + +PS = $(addsuffix .ps, $(HTML)) + +DVI = $(addsuffix .dvi, $(HTML)) + +TXT = $(addsuffix .txt, $(HTML)) + +PDF = $(addsuffix .pdf, $(HTML)) + +CHAPTERS = $(addsuffix .tex, crt dos getopts go32 graph linux printer strings) + +.PHONY: clean dvi help html ps psdist htmldist htm txt pdf refex + +.SUFFIXES: .dvi .tex .ps .txt .pdf + +.dvi.ps: + $(DVIPS) $< + +.tex.dvi: + $(LATEX) $* + -$(MAKEINDEX) $* + $(LATEX) $* + -$(MAKEINDEX) $* + $(LATEX) $* + +.dvi.txt: + $(DVITXT) -o $*.txt $*.dvi + +.tex.pdf: + $(PDFLATEX) $*pdf + -$(MAKEINDEX) $*pdf + $(PDFLATEX) $*pdf + -$(MAKEINDEX) $*pdf + $(PDFLATEX) $*pdf + +help: + @echo 'Possible targets :' + @echo ' dvi : Make documentation using latex.' + @echo ' ps : Make documentation using latex and dvips.' + @echo ' html : Make documentation using latex2html.' + @echo ' htm : Convert .html to .htm files, zip result' + @echo ' clean : Clean up the mess.' + + +$(TXT) : %.txt: %.dvi + +$(DVI) : %.dvi: %.tex + +$(PDF) : %.pdf: %.tex + +units.dvi: units.tex $(CHAPTERS) unitex + +unitex: + $(MAKE) -C crtex tex + $(MAKE) -C linuxex tex + $(MAKE) -C dosex tex + $(MAKE) -C optex tex + $(MAKE) -C printex tex + $(MAKE) -C stringex tex + $(MAKE) -C sockex tex + +ref.dvi: ref.tex refex + +refex: + $(MAKE) -C refex tex + +dvi : $(DVI) + +txt : dvi $(TXT) + +html : dvi $(HTML) + +ps : dvi $(PS) + +pdf : $(PDF) + +user: + $(LATEX2HTML) $(LATEX2HTMLOPTS) -split 2 -link 2\ + -t "User's guide for FPK Pascal" user.tex + sed -f foot.sed user/footnote.html + mv user/footnote.html user/footnode.html + +units: + $(LATEX2HTML) $(LATEX2HTMLOPTS) -split 3 -link 2\ + -t "Unit reference for FPK Pascal" units.tex + sed -f foot.sed units/footnote.html + mv units/footnote.html units/footnode.html + +ref: + $(LATEX2HTML) $(LATEX2HTMLOPTS) -split 3 -link 2\ + -t "FPK Pascal reference guide" ref.tex + sed -f foot.sed ref/footnote.html + mv ref/footnote.html ref/footnode.html + +prog: + $(LATEX2HTML) $(LATEX2HTMLOPTS) -split 2 -link 2\ + -t "FPK Pascal programmers guide" prog.tex + sed -f foot.sed prog/footnote.html + mv prog/footnote.html prog/footnode.html + +clean: + -rm -f *.aux *.log *.dvi *.ps *.toc *.i* *.lot *.pdf *.txt + -rm -rf $(HTML) + -$(MAKE) -C refex clean + -$(MAKE) -C linuxex clean + -$(MAKE) -C crtex clean + -$(MAKE) -C dosex clean + -$(MAKE) -C optex clean + -$(MAKE) -C printex clean + -$(MAKE) -C stringex clean + -$(MAKE) -C sockex clean + +htmldist: html + find . -name '*.html' >htmllist + find . -name '*.gif' >>htmllist + tar -czvf fpcdoc.tar.gz --files-from=htmllist + rm -f htmllist + +psdist: ps + tar -cvzf fpcdocps.tar.gz *.ps + zip fpcdocps *.ps + +pdfdist: pdf + zip fpcdocpdf *.pdf + + +htm: + makehtm `find . -name '*.html'` + zip fpcdoc `find . -name '*.htm'` + rm `find -name '*.htm'` + +dist: + -mkdir $(DISTDIR)/docs + cp Makefile README.DOCS makehtm fpktoc.html $(DISTDIR)/docs + cp *.tex *.sty *.perl *.doc $(DISTDIR)/docs + +distclean: clean + -rm -f *.tar.gz *.zip + +install: html + install -d -m 755 $(DOCINSTALLDIR) + cp -R $(HTML) $(DOCINSTALLDIR) + cp fpctoc.html $(DOCINSTALLDIR) + +www-install: psdist htmldist htm + rcp fpcdoc.zip fpcdocps.zip fpcdocps.tar.gz fpcdoc.tar.gz tfdec1:htdocs/fpk + rsh tfdec1 '(cd htdocs/fpk/docs ; /usr/local/bin/tar -xzf ../fpcdoc.tar.gz)' + +all-formats: ps txt pdf html diff --git a/docs/README.DOCS b/docs/README.DOCS new file mode 100644 index 0000000000..981eb13dc7 --- /dev/null +++ b/docs/README.DOCS @@ -0,0 +1,51 @@ +This is the README for the FPK linux documentation. + +All documentation is stored here, in LaTeX format. +it uses special style files (fpk*.sty) which are also in the directory. + +do a 'make dvi' to produce the dvi format of the docs. +a 'make html' will produce the html version (using latex2html). +a 'make ps' will produce PostScript documents. + +If you want to produce dos docs, you can do a 'make htm' this will convert +the .htl files to .htm files (including all references), suitable for a 8:3 +format. + +The rest of this document is only interesting if you want to write docs. +Otherwise, you can bail out now. + +THE DOCS... + +Why LaTeX ? +- because I like a printed copy of the manuals, HTML just isn't good enough + for this. +- I know LaTeX very well :) (mind you : html also !) +- many other reasons. + +In order to translate the things to HTML, I use latex2html, since it is the +most powerful and flexible. +For it to be able to use the fpk.sty, I had to write a fpk.perl script +which it loads. The script seems to run fine when used standalone, but in +conjunction with latex2html, I get a out of memory... ?? +I'm not familiar with perl, so if someone is, and can fix the thing, please +do. (and let me know :) ) + +Then how to proceed ? +If you just want to write latex docs, just use fpk.sty. (you don't need +html.sty) +If you want to be able to convert to html, (you need html.sty) the following +fixes the perl-problem : +In the preamble of your document, type : + +\usepackage{html} +\latex{\usepackage{fpk}} +\html{\input{fpk-html.tex}} + +The fpk-html.tex defines the same commands as fpk.sty, only in a language +that latex2html understands. + +fpk.sty.doc describes what fpk.sty does. (one day I'll integrate them using +the doc package, but I need some time for it) + +Happy TeXing, +Michael. \ No newline at end of file diff --git a/docs/crt.tex b/docs/crt.tex new file mode 100644 index 0000000000..6066743fd7 --- /dev/null +++ b/docs/crt.tex @@ -0,0 +1,342 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\chapter{The CRT unit.} +This chapter describes the \var{CRT} unit for Free Pascal, both under \dos +and \linux. The unit was first written for \dos by Florian kl\"ampfl. + +The unit was ported to \linux by Mark May\footnote{Current +e-mail address \textsf{mmay@dnaco.net}}, and enhanced by Micha\"el Van Canneyt +It works on the \linux console, and in xterm and rxvt windows under +X-Windows. The functionality for both is the same, except that under \linux +the use of an early implementation (versions 0.9.1 an earlier of the +compiler) the crt unit automatically cleared the screen at program startup. + +This chapter is divided in two sections. +\begin{itemize} +\item The first section lists the pre-defined constants, types and variables. +\item The second section describes the functions which appear in the +interface part of the CRT unit. +\end{itemize} + +\section{Types, Variables, Constants} +Color definitions : +\begin{verbatim} + Black = 0; + Blue = 1; + Green = 2; + Cyan = 3; + Red = 4; + Magenta = 5; + Brown = 6; + LightGray = 7; + DarkGray = 8; + LightBlue = 9; + LightGreen = 10; + LightCyan = 11; + LightRed = 12; + LightMagenta = 13; + Yellow = 14; + White = 15; + Blink = 128; +\end{verbatim} +Miscellaneous constants +\begin{verbatim} + TextAttr: Byte = $07; + TextChar: Char = ' '; + CheckBreak: Boolean = True; + CheckEOF: Boolean = False; + CheckSnow: Boolean = False; + DirectVideo: Boolean = False; + LastMode: Word = 3; + WindMin: Word = $0; + WindMax: Word = $184f; + ScreenWidth = 80; + ScreenHeight = 25; +\end{verbatim} +Some variables for compatibility with Turbo Pascal. However, they're not +used by \fpk. +\begin{verbatim} +var + checkbreak : boolean; + checkeof : boolean; + checksnow : boolean; +\end{verbatim} +The following constants define screen modes on a \dos system: +\begin{verbatim} +Const + bw40 = 0; + co40 = 1; + bw80 = 2; + co80 = 3; + mono = 7; +\end{verbatim} +The \var{TextAttr} variable controls the attributes with which characters +are written to screen. +\begin{verbatim} +var TextAttr : byte; +\end{verbatim} +The \var{DirectVideo} variable controls the writing to the screen. If it is +\var{True}, the the cursor is set via direct port access. If \var{False}, +then the BIOS is used. This is defined under \dos only. +\begin{verbatim} +var DirectVideo : Boolean; +\end{verbatim} +The \var{Lastmode} variable tells you which mode was last selected for the +screen. It is defined on \dos only. +\begin{verbatim} +var lastmode : Word; +\end{verbatim} + +\section{Procedures and Functions} +\procedure{AssignCrt}{(Var F: Text)} +{ +Assigns a file F to the console. Everything written to the file F goes to +the console instead. If the console contains a window, everything is written +to the window instead. +} +{None.}{\seep{Window}} + +\input{crtex/ex1.tex} + +\procedure{Delay}{(DTime: Word)} +{Delay waits a specified number of milliseconds. The number of specified +seconds is a approximation, and may be off a lot, if system load is high.} +{None}{\seep{Sound}, \seep{NoSound}} + +\input{crtex/ex15.tex} + +\procedure {TextColor}{(CL: Byte)} +{ +TextColor sets the foreground color to \var{CL}. \var{CL} can be one of the +predefined color constants. +} +{None.}{ \seep{TextBackground}, \seep{HighVideo}, \seep{LowVideo}, +\seep{NormVideo}} + +\input{crtex/ex12.tex} + +\procedure {TextBackground}{(CL: Byte)} +{ +TextBackground sets the background color to \var{CL}. \var{CL} can be one of the +predefined color constants. +} +{None.}{ \seep{TextColor}, \seep{HighVideo}, \seep{LowVideo}, +\seep{NormVideo}} + +\input{crtex/ex13.tex} + +\procedure {HighVideo}{} +{ HighVideo switches the output to highlighted text. (It sets the high +intensity bit of the video attribute) +} +{None.}{ \seep{TextColor}, \seep{TextBackground}, \seep{LowVideo}, +\seep{NormVideo}} + +\input{crtex/ex14.tex} + +\Procedure {LowVideo} +{ LowVideo switches the output to non-highlighted text. (It clears the high +intensity bit of the video attribute) +} +{None.}{ \seep{TextColor}, \seep{TextBackground}, \seep{HighVideo}, +\seep{NormVideo}} + +For an example, see \seep{HighVideo} + +\Procedure {NormVideo} +{ NormVideo switches the output to the defaults, read at startup. (The +defaults are read from the cursor position at startup) +} +{None.}{ \seep{TextColor}, \seep{TextBackground}, \seep{LowVideo}, +\seep{HighVideo}} + +For an example, see \seep{HighVideo} + +\Procedure{BigCursor}{Makes the cursor a big rectangle. + +Not implemented on \linux.} +{None.}{\seep{CursorOn}, \seep{CursorOff}} + +\Procedure{CursorOn}{Switches the cursor on. + +Not implemented on \linux.} +{None.}{\seep{BigCursor}, \seep{CursorOff}} + +\Procedure{CursorOff}{Switches the cursor off (i.e. the cursor is no +longer visible). + +Not implemented on \linux.} +{None.}{\seep{CursorOn}, \seep{BigCursor}} + +\procedure {GotoXY}{(X: Byte; Y: Byte)} +{ Positions the cursor at \var{(X,Y)}, \var{X} in horizontal, \var{Y} in +vertical direction relative to the origin of the current window. The origin +is located at \var{(1,1)}, the upper-left corner of the window. +} +{None.}{ \seef{WhereX}, \seef{WhereY}, \seep{Window} } + +\input{crtex/ex6.tex} + +\Function {WhereX}{Byte} +{ +WhereX returns the current X-coordinate of the cursor, relative to the +current window. The origin is \var{(1,1)}, in the upper-left corner of the +window. +} +{None.}{ \seep{GotoXY}, \seef{WhereY}, \seep{Window} } + + +\input{crtex/ex7.tex} + +\Function {WhereY}{Byte} +{ +WhereY returns the current Y-coordinate of the cursor, relative to the +current window. The origin is \var{(1,1)}, in the upper-left corner of the +window. +} +{None.}{ \seep{GotoXY}, \seef{WhereX}, \seep{Window} } + +\input{crtex/ex7.tex} + +\procedure {Window}{(X1, Y1, X2, Y2: Byte)} +{ Window creates a window on the screen, to which output will be sent. +\var{(X1,Y1)} are the coordinates of the upper left corner of the window, +\var{(X2,Y2)} are the coordinates of the bottom right corner of the window. +These coordinates are relative to the entire screen, with the top left +corner equal to \var{(1,1)} + +Further coordinate operations, except for the next Window call, +are relative to the window's top left corner. +} +{None.}{\seep{GotoXY}, \seef{WhereX}, \seef{WhereY}, \seep{ClrScr}} + +\input{crtex/ex5.tex} + + +\procedure {ClrScr}{} +{ ClrScr clears the current window (using the current colors), +and sets the cursor in the top left +corner of the current window.} +{None.}{ \seep{Window} } + +\input{crtex/ex8.tex} + + +%\procedure {ScrollWindow}{(X1,Y1,X2,Y2 : Byte; Count : Longint)} +%{ ScrollWindow scrolls the contents of the window defined by the upper-left +%\var{(X1,Y1)} and lower-right \var{(X2,Y2)} corners \var{count} lines up if +%\var{count} is positive, it scrolls down if \var{count} is negative. +%The new lines are made blank using the current textcolors. +%} +%{None.}{\seep{Window}, \seep{ClrScr}} + +%\function {SaveScreenRegion}{(X1,Y1,X2,Y2, var P : pointer)}{Boolean} +%{SaveScreenRegion writes the the contents of the window defined by the upper-left +%\var{(X1,Y1)} and lower-right \var{(X2,Y2)} corners to the location pointed +%to by \var{P}. If \var{P} is \var{nil} then enough memory is allocated to +%contain the contents of the window. +% +%The contents are written as follows : line per line, column per column, +%first the character on screen is written (1 byte), followed by the text +%attribute (1 byte). The size required is therefore +%\var{(Y2-Y1+1)*(X2-X1+1)*2} bytes. +% +%The function returns \var{False} if it couldn't allocate the required +%memory, \var{True} if the memory was allocated.}{None.} +%{\seep{RestoreScreenRegion}, \seep{Window} } + +%\procedure {RestoreScreenRegion}{(X1,Y1,X2,Y2, var P : pointer)} +%{SaveScreenRegion writes the the contents of the memory location pointed to +%by \var{P}, to the window defined by the upper-left \var{(X1,Y1)} and +%lower-right \var{(X2,Y2)} corners. +% +%The contents of \var{P} should be arranged as if they are when written by +%a call to the SaveScreenRegion () function. +% +%The memory pointed to by \var{P} is NOT freed.}{None} +%{\seef{SaveScreenRegion}, \seep{Window} } + + +\Procedure {ClrEol} +{ ClrEol clears the current line, starting from the cursor position, to the +end of the window. The cursor doesn't move} +{None.}{\seep{DelLine}, \seep{InsLine}, \seep{ClrScr}} + +\input{crtex/ex9.tex} + + +\Procedure {DelLine} +{ DelLine removes the current line. Lines following the current line are +scrolled 1 line up, and an empty line is inserted at the bottom of the +current window. The cursor doesn't move.} +{None.}{\seep{ClrEol}, \seep{InsLine}, \seep{ClrScr}} + +\input{crtex/ex11.tex} + + +\procedure {InsLine}{} +{ InsLine inserts an empty line at the current cursor position. +Lines following the current line are scrolled 1 line down, +causing the last line to disappear from the window. +The cursor doesn't move.} +{None.}{\seep{ClrEol}, \seep{DelLine}, \seep{ClrScr}} + +\input{crtex/ex10.tex} + + +\Function {KeyPressed}{Boolean} +{ The Keypressed function scans the keyboard buffer and sees if a key has +been pressed. If this is the case, \var{True} is returned. If not, +\var{False} is returned. The \var{Shift, Alt, Ctrl} are not reported. +The key is not removed from the buffer, and can hence still be read after +the KeyPressed function has been called. +} +{None.}{\seef{ReadKey}} + +\input{crtex/ex2.tex} + + +\Function {ReadKey}{Char} +{ +The ReadKey function reads 1 key from the keyboard buffer, and returns this. +If an extended or function key has been pressed, then the zero ASCII code is +returned. You can then read the scan code of the key with a second ReadKey +call. + +\textbf{Remark.} Key mappings under Linux can cause the wrong key to be +reported by ReadKey, so caution is needed when using ReadKey. +} +{None.}{\seef{KeyPressed}} + +\input{crtex/ex3.tex} + + +\procedure{Sound}{(hz : word)} +{ Sounds the speaker at a frequency of \var{hz}. + +This is not supported in \linux}{None.}{\seep{NoSound}} +\Procedure{NoSound}{ +Stops the speaker sound. + +This is not supported in \linux}{None.}{\seep{Sound}} + +\input{crtex/ex16.tex} + diff --git a/docs/crtex/Makefile b/docs/crtex/Makefile new file mode 100644 index 0000000000..0cdf2c2748 --- /dev/null +++ b/docs/crtex/Makefile @@ -0,0 +1,54 @@ +####################################################################### +# +# Makefile to compile all examples and convert them to LaTeX +# +####################################################################### + +# Compiler +PP=ppc386 + +# Unit directory +# UNITDIR=/usr/lib/ppc/0.99.0/linuxunits + + +# Any options you wish to pass. +PPOPTS= + +# Script to convert the programs to LaTeX examples which can be included. +PP2TEX=pp2tex + +# Script to collect all examples in 1 file. +MAKETEX=make1tex + +####################################################################### +# No need to edit after this line. +####################################################################### + +ifdef UNITDIR +PPOPTS:=$(PPOPTS) -Up$(UNITDIR); +endif + +.SUFFIXES: .pp .tex + +.PHONY: all tex clean + +OBJECTS=ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex11 ex12 ex13 ex14 \ + ex15 ex16 + +TEXOBJECTS=$(addsuffix .tex, $(OBJECTS)) + +all : $(OBJECTS) + +tex : $(TEXOBJECTS) + +onetex : tex + $(MAKETEX) $(TEXOBJECTS) + +clean : + rm -f *.o *.s $(OBJECTS) $(TEXOBJECTS) + +$(OBJECTS): %: %.pp + $(PP) $(PPOPTS) $* + +$(TEXOBJECTS): %.tex: %.pp head.tex foot.tex + $(PP2TEX) $* diff --git a/docs/crtex/README b/docs/crtex/README new file mode 100644 index 0000000000..16d8642445 --- /dev/null +++ b/docs/crtex/README @@ -0,0 +1,21 @@ +These are the example programs that appear in the FPC documentation. +These examples were written by Peter Vreman (pfv@worldonline.nl) + +Units guide, chapter on CRT unit : + +ex1.pp contains an example of the AssignCrt function. +ex2.pp contains an example of the KeyPressed function. +ex3.pp contains an example of the ReadKey function. +ex4.pp contains an example of the TextMode function. +ex5.pp contains an example of the Window function. +ex6.pp contains an example of the GotoXY function. +ex7.pp contains an example of the WhereX and WhereY functions. +ex8.pp contains an example of the ClrScr function. +ex9.pp contains an example of the ClrEol function. +ex10.pp contains an example of the InsLine function. +ex11.pp contains an example of the DelLine function. +ex12.pp contains an example of the TextColor function. +ex13.pp contains an example of the TextBackground function. +ex14.pp contains an example of the LowVideo, HighVideo, NormVideo functions. +ex15.pp contains an example of the Delay function. +ex16.pp contains an example of the Sound function. diff --git a/docs/crtex/ex1.pp b/docs/crtex/ex1.pp new file mode 100644 index 0000000000..f72a2f1af9 --- /dev/null +++ b/docs/crtex/ex1.pp @@ -0,0 +1,13 @@ +Program Example1; +uses Crt; + +{ Program to demonstrate the AssignCrt function. } + +var + F : Text; +begin + AssignCrt(F); + Rewrite(F); { Don't forget to open for output! } + WriteLn(F,'This is written to the Assigned File'); + Close(F); +end. diff --git a/docs/crtex/ex10.pp b/docs/crtex/ex10.pp new file mode 100644 index 0000000000..535968bd91 --- /dev/null +++ b/docs/crtex/ex10.pp @@ -0,0 +1,18 @@ +Program Example10; +uses Crt; + +{ Program to demonstrate the InsLine function. } + +begin + ClrScr; + WriteLn; + WriteLn('Line 1'); + WriteLn('Line 3'); + WriteLn; + WriteLn('Oops, forgot Line 2, let''s insert at the cursor postion'); + GotoXY(1,3); + ReadKey; + InsLine; + Write('Line 2'); + GotoXY(1,10); +end. diff --git a/docs/crtex/ex11.pp b/docs/crtex/ex11.pp new file mode 100644 index 0000000000..634c3cf2c1 --- /dev/null +++ b/docs/crtex/ex11.pp @@ -0,0 +1,19 @@ +Program Example10; +uses Crt; + +{ Program to demonstrate the InsLine function. } + +begin + ClrScr; + WriteLn; + WriteLn('Line 1'); + WriteLn('Line 2'); + WriteLn('Line 2'); + WriteLn('Line 3'); + WriteLn; + WriteLn('Oops, Line 2 is listed twice, let''s delete the line at the cursor postion'); + GotoXY(1,3); + ReadKey; + DelLine; + GotoXY(1,10); +end. diff --git a/docs/crtex/ex12.pp b/docs/crtex/ex12.pp new file mode 100644 index 0000000000..66907805d6 --- /dev/null +++ b/docs/crtex/ex12.pp @@ -0,0 +1,14 @@ +Program Example12; +uses Crt; + +{ Program to demonstrate the TextColor function. } + +begin + WriteLn('This is written in the default color'); + TextColor(Red); + WriteLn('This is written in Red'); + TextColor(White); + WriteLn('This is written in White'); + TextColor(LightBlue); + WriteLn('This is written in Light Blue'); +end. diff --git a/docs/crtex/ex13.pp b/docs/crtex/ex13.pp new file mode 100644 index 0000000000..10f33420a7 --- /dev/null +++ b/docs/crtex/ex13.pp @@ -0,0 +1,15 @@ +Program Example13; +uses Crt; + +{ Program to demonstrate the TextBackground function. } + +begin + TextColor(White); + WriteLn('This is written in with the default background color'); + TextBackground(Green); + WriteLn('This is written in with a Green background'); + TextBackground(Brown); + WriteLn('This is written in with a Brown background'); + TextBackground(Black); + WriteLn('Back with a black background'); +end. diff --git a/docs/crtex/ex14.pp b/docs/crtex/ex14.pp new file mode 100644 index 0000000000..c3cf302d7c --- /dev/null +++ b/docs/crtex/ex14.pp @@ -0,0 +1,13 @@ +Program Example14; +uses Crt; + +{ Program to demonstrate the LowVideo, HighVideo, NormVideo functions. } + +begin + LowVideo; + WriteLn('This is written with LowVideo'); + HighVideo; + WriteLn('This is written with HighVideo'); + NormVideo; + WriteLn('This is written with NormVideo'); +end. diff --git a/docs/crtex/ex15.pp b/docs/crtex/ex15.pp new file mode 100644 index 0000000000..a368b5bade --- /dev/null +++ b/docs/crtex/ex15.pp @@ -0,0 +1,15 @@ +Program Example15; +uses Crt; + +{ Program to demonstrate the Delay function. } +var + i : longint; +begin + WriteLn('Counting Down'); + for i:=10 downto 1 do + begin + WriteLn(i); + Delay(1000); {Wait one second} + end; + WriteLn('BOOM!!!'); +end. diff --git a/docs/crtex/ex16.pp b/docs/crtex/ex16.pp new file mode 100644 index 0000000000..0ca3b9a50a --- /dev/null +++ b/docs/crtex/ex16.pp @@ -0,0 +1,18 @@ +Program Example16; +uses Crt; + +{ Program to demonstrate the Sound and NoSound function. } + +var + i : longint; +begin + WriteLn('You will hear some tones from your speaker'); + while (i<15000) do + begin + inc(i,500); + Sound(i); + Delay(100); + end; + WriteLn('Quiet now!'); + NoSound; {Stop noise} +end. diff --git a/docs/crtex/ex2.pp b/docs/crtex/ex2.pp new file mode 100644 index 0000000000..65c7b88969 --- /dev/null +++ b/docs/crtex/ex2.pp @@ -0,0 +1,11 @@ +Program Example2; +uses Crt; + +{ Program to demonstrate the KeyPressed function. } + +begin + WriteLn('Waiting until a key is pressed'); + repeat + until KeyPressed; +{The key is not Read, so it should also be outputted at the commandline} +end. diff --git a/docs/crtex/ex3.pp b/docs/crtex/ex3.pp new file mode 100644 index 0000000000..9a42730fd8 --- /dev/null +++ b/docs/crtex/ex3.pp @@ -0,0 +1,23 @@ +Program Example3; +uses Crt; + +{ Program to demonstrate the ReadKey function. } + +var + ch : char; +begin + writeln('Press Left/Right, Esc=Quit'); + repeat + ch:=ReadKey; + case ch of + #0 : begin + ch:=ReadKey; {Read ScanCode} + case ch of + #75 : WriteLn('Left'); + #77 : WriteLn('Right'); + end; + end; + #27 : WriteLn('ESC'); + end; + until #ch=27 {Esc} +end. diff --git a/docs/crtex/ex4.pp b/docs/crtex/ex4.pp new file mode 100644 index 0000000000..716d2d6a1e --- /dev/null +++ b/docs/crtex/ex4.pp @@ -0,0 +1,13 @@ +Program Example4; +uses Crt; + +{ Program to demonstrate the TextMode function. } + +begin + TextMode(CO40); {Only clears screen under linux} + WriteLn('Mode 40x25 Color'); + ReadKey; + TextMode(CO80); + WriteLn('Back in Mode 80x25 Color'); + ReadKey; +end. diff --git a/docs/crtex/ex5.pp b/docs/crtex/ex5.pp new file mode 100644 index 0000000000..d01fc26f72 --- /dev/null +++ b/docs/crtex/ex5.pp @@ -0,0 +1,21 @@ +Program Example5; +uses Crt; + +{ Program to demonstrate the Window function. } + +begin + ClrScr; + WriteLn('Creating a window from 30,10 to 50,20'); + Window(30,10,50,20); + WriteLn('We are now writing in this small window we just created, we '+ + 'can''t get outside it when writing long lines like this one'); + Write('Press any key to clear the window'); + ReadKey; + ClrScr; + Write('The window is cleared, press any key to restore to fullscreen'); + ReadKey; +{Full Screen is 80x25} + Window(1,1,80,25); + Clrscr; + Writeln('Back in Full Screen'); +end. diff --git a/docs/crtex/ex6.pp b/docs/crtex/ex6.pp new file mode 100644 index 0000000000..66ded0a51d --- /dev/null +++ b/docs/crtex/ex6.pp @@ -0,0 +1,13 @@ +Program Example6; +uses Crt; + +{ Program to demonstrate the GotoXY function. } + +begin + ClrScr; + GotoXY(10,10); + Write('10,10'); + GotoXY(70,20); + Write('70,20'); + GotoXY(1,22); +end. diff --git a/docs/crtex/ex7.pp b/docs/crtex/ex7.pp new file mode 100644 index 0000000000..f04174eb8b --- /dev/null +++ b/docs/crtex/ex7.pp @@ -0,0 +1,8 @@ +Program Example7; +uses Crt; + +{ Program to demonstrate the WhereX and WhereY functions. } + +begin + Writeln('Cursor postion: X=',WhereX,' Y=',WhereY); +end. diff --git a/docs/crtex/ex8.pp b/docs/crtex/ex8.pp new file mode 100644 index 0000000000..1fd1f2a74d --- /dev/null +++ b/docs/crtex/ex8.pp @@ -0,0 +1,11 @@ +Program Example8; +uses Crt; + +{ Program to demonstrate the ClrScr function. } + +begin + Writeln('Press any key to clear the screen'); + ReadKey; + ClrScr; + Writeln('Have fun with the cleared screen'); +end. diff --git a/docs/crtex/ex9.pp b/docs/crtex/ex9.pp new file mode 100644 index 0000000000..cdb9583d09 --- /dev/null +++ b/docs/crtex/ex9.pp @@ -0,0 +1,12 @@ +Program Example9; +uses Crt; + +{ Program to demonstrate the ClrEol function. } + +begin + Write('This line will be cleared from the cursor postion until the right of the screen'); + GotoXY(27,WhereY); + ReadKey; + ClrEol; + WriteLn; +end. diff --git a/docs/crtex/foot.tex b/docs/crtex/foot.tex new file mode 100644 index 0000000000..83788a402a --- /dev/null +++ b/docs/crtex/foot.tex @@ -0,0 +1,2 @@ +\end{verbatim} +\end{FPKList} \ No newline at end of file diff --git a/docs/crtex/head.tex b/docs/crtex/head.tex new file mode 100644 index 0000000000..b2ed5b6603 --- /dev/null +++ b/docs/crtex/head.tex @@ -0,0 +1,3 @@ +\begin{FPKList} +\item[Example] +\begin{verbatim} diff --git a/docs/crtex/pp2tex b/docs/crtex/pp2tex new file mode 100644 index 0000000000..3a5cd6a448 --- /dev/null +++ b/docs/crtex/pp2tex @@ -0,0 +1,5 @@ +#!/bin/sh +# Simply paste a header and footer to the program. +cat head.tex > $1.tex +cat $1.pp >> $1.tex +cat foot.tex >> $1.tex diff --git a/docs/dos.tex b/docs/dos.tex new file mode 100644 index 0000000000..a86a42cb7f --- /dev/null +++ b/docs/dos.tex @@ -0,0 +1,558 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\chapter{The DOS unit.} +This chapter describes the \var{DOS} unit for Free pascal, both under \dos +and \linux. The unit was first written for \dos by Florian kl\"ampfl. + +The unit was ported to \linux by Mark May\footnote{Current +e-mail address \textsf{mmay@dnaco.net}}, and enhanced by Micha\"el Van +Canneyt. +Under \linux, some of the functionality is lost, as it is either impossible +or meaningless to implement it. Other than that, +the functionality for both operating systems is the same. + +This chapter is divided in two sections. +\begin{itemize} +\item The first section lists the pre-defined constants, types and variables. +\item The second section describes the functions which appear in the +interface part of the DOS unit. +\end{itemize} + +\section{Types, Variables, Constants} +\subsection {Constants} +The DOS unit implements the following constants: +\begin{verbatim} + {Bitmasks for CPU Flags} + fcarry = $0001; + fparity = $0004; + fauxiliary = $0010; + fzero = $0040; + fsign = $0080; + foverflow = $0800; + + {Bitmasks for file attribute} + readonly = $01; + hidden = $02; + sysfile = $04; + volumeid = $08; + directory = $10; + archive = $20; + anyfile = $3F; + fmclosed = $D7B0; + fminput = $D7B1; + fmoutput = $D7B2; + fminout = $D7B3; +\end{verbatim} +\subsection{Types} +The following string types are defined for easy handling of +filenames : +\begin{verbatim} + ComStr = String[127]; { For command-lines } + PathStr = String[79]; { For full path for file names } + DirStr = String[67]; { For Directory and (DOS) drive string } + NameStr = String[8]; { For Name of file } + ExtStr = String[4]; { For Extension of file } +\end{verbatim} +Under \linux, these strings all have length 255. +\begin{verbatim} +{$PACKRECORDS 1} + SearchRec = Record + Fill : array[1..21] of byte; + { Fill replaced with declarations below, for Linux} + Attr : Byte; {attribute of found file} + Time : LongInt; {last modify date of found file} + Size : LongInt; {file size of found file} + Reserved : Word; {future use} + Name : String[255]; {name of found file} + SearchSpec: String[255]; {search pattern} + NamePos: Word; {end of path, start of name position} + End; +\end{verbatim} +Under \linux, the \var{Fill} array is replaced with the following: +\begin{verbatim} + SearchNum: LongInt; {to track which search this is} + SearchPos: LongInt; {directory position} + DirPtr: LongInt; {directory pointer for reading directory} + SearchType: Byte; {0=normal, 1=open will close} + SearchAttr: Byte; {attribute we are searching for} + Fill: Array[1..07] of Byte; {future use} +\end{verbatim} +This is because the searching meachanism on Unix systems is substantially +different from \dos's, and the calls have to be mimicked. +\begin{verbatim} +{$PACKRECORDS 2} + FileRec = Record + Handle : word; + Mode : word; + RecSize : word; + _private : array[1..26] of byte; + UserData: array[1..16] of byte; + Name: array[0..255] of char; + End; +\end{verbatim} +\var{FileRec} is used for internal representation of typed and untyped files. +Text files are handled by the following types : +\begin{verbatim} + TextBuf = array[0..127] of char; + + TextRec = record + handle : word; + mode : word; + bufSize : word; + _private : word; + bufpos : word; + bufend : word; + bufptr : ^textbuf; + openfunc : pointer; + inoutfunc : pointer; + flushfunc : pointer; + closefunc : pointer; + userdata : array[1..16] of byte; + name : array[0..127] of char; + buffer : textbuf; + End; +\end{verbatim} +The size of the \var{name} field is 255 under \linux. +\begin{verbatim} + Registers = record + case i : integer of + 0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si, + f51,di,f6,ds,f7,es,f8,flags,fs,gs : word); + 1 : (al,ah,f9,f10,bl,bh,f11,f12, + cl,ch,f13,f14,dl,dh : byte); + 2 : (eax, ebx, ecx, edx, ebp, esi, edi : longint); + End; +\end{verbatim} +The \var{registers} type is used in the var{\var{MSDos} call. +\begin{verbatim} + DateTime = record + Year: Word; + Month: Word; + Day: Word; + Hour: Word; + Min: Word; + Sec: word; + End; +\end{verbatim} +The \var{DateTime} type is used in \seep{PackTime} and \seep{UnPackTime} for +setting/reading file times with \seep{GetFTime} and \seep{SetFTime}. + +\subsection{Variables} +\begin{verbatim} + DosError : integer; +\end{verbatim} +The \var{DosError} variable is used by the procedures in the \dos unit to +report errors. It can have the following values : +\begin{center} +\begin{tabular}{cl} +2 & File not found. \\ +3 & path not found. \\ +5 & Access denied. \\ +6 & Invalid handle. \\ +8 & Not enough memory. \\ +10 & Invalid environment. \\ +11 & Invalid format. \\ +18 & No more files. +\end{tabular} +\end{center} +Other values are possible, but are not documented. +%\begin{verbatim} +% drivestr : array [0..26] of pchar; +%\end{verbatim} +%This variable is defined in the \linux version of the \dos unit. It is used +%in the \seef{DiskFree} and \seef{DiskSize} calls. + +\section{Functions and Procedures} + +\procedure{AddDisk}{(Const S : String)} +{\var{AddDisk} adds a filenme \var{S} to the internal list of filenames. + This list is used to determine which disks to use in the \seef{DiskFree} +and \seef{DiskSize} calls. The names are added sequentially. The dos +initialization code presets the first three disks to: +\begin{itemize} +\item \var{'.'} for the current drive, +\item \var{'/fd0/.'} for the first floppy-drive. +\item \var{'/fd1/.'} for the second floppy-drive. +\item \var{'/'} for the first hard disk. +\end{itemize} +The first call to \var{AddDisk} will therefore add a name for the second +harddisk, The second call for the third drive, and so on until 23 drives +have been added (corresponding to \var{'D:'} to \var{'Z:'}) +}{None}{\seef{DiskFree}, \seef{DiskSize} } + +\function{DiskFree}{(Drive: byte)}{longint}{ +\var{DiskFree} returns the number of free bytes on a disk. The parameter +\var{Drive} indicates which disk should be checked. This parameter is 1 for +floppy \var{a:}, 2 for floppy \var{b:}, etc. A value of 0 returns the free +space on the current drive. + +Typically, the free space is the size of a disk block, multiplied by the +number of free blocks on the disk. + +\textbf{For \linux only:}\\ +The \var{diskfree} and \var{disksize} functions need a file on the specified drive, since this +is required for the \var{statfs} system call. + These filenames are set in the initialization of the dos unit, and have +been preset to : +\begin{itemize} +\item \var{'.'} for the current drive, +\item \var{'/fd0/.'} for the first floppy-drive. +\item \var{'/fd1/.'} for the second floppy-drive. +\item \var{'/'} for the first hard disk. +\end{itemize} +There is room for 1-26 drives. You can add a drive with the +\seep{AddDisk} procedure. + +These settings can be coded in \var{dos.pp}, in the initialization part. +}{-1 when a failure occurs, or an invalid \var{drivenr} is given.} +{\seef{DiskSize}} + +\input{dosex/ex6.tex} + +\function{DiskSize}{(Drive: byte)}{longint}{ +\var{DiskSize} returns the total size (in bytes) of a disk. The parameter +\var{Drive} indicates which disk should be checked. This parameter is 1 for +floppy \var{a:}, 2 for floppy \var{b:}, etc. A value of 0 returns the size +of the current drive. + +\textbf{For \linux only:}\\ +The \var{diskfree} and \var{disksize} functions need a file on the specified drive, since this +is required for the \var{statfs} system call. + These filenames are set in the initialization of the dos unit, and have +been preset to : +\begin{itemize} +\item \var{'.'} for the current drive, +\item \var{'/fd0/.'} for the first floppy-drive. +\item \var{'/fd1/.'} for the second floppy-drive. +\item \var{'/'} for the first hard disk. +\end{itemize} +There is room for 1-26 drives. You can add a drive with the +\seep{AddDisk} procedure. + +These settings can be coded in \var{dos.pp}, in the initialization part. +}{-1 when a failure occurs, or an invalid drive number is given.} +{\seef{DiskFree}} + +For an example, see \seef{DiskFree}. + +\Function{DosExitCode}{Word}{ +\var{DosExitCode} contains (in the low byte) the exit-code of a program +executed with the \var{Exec} call.}{None.}{\seep{Exec}} + +\input{dosex/ex5.tex} + +\Function{DosVersion}{Word} +{\var{DosVersion} returns the \dos version number. On \linux systems, it +returns the Linux version (The first 2 numbers, e.g Linux version 2.1.76 will +give you DosVersion 2.1)}{None.}{} + +\input{dosex/ex1.tex} + +\Function{EnvCount}{longint}{ +\var{EnvCount} returns the number of environment variables.} +{None.}{\seef{EnvStr}, \seef{GetEnv}} +\function{EnvStr}{(Index: integer)}{string}{ +\var{EnvStr} returns the \var{Index}-th \var{Name=Value} pair from the list +of environment variables. + +The index of the first pair is zero.} +{The length is limited to 255 characters. This may cause problems under +\linux. The \linux unit solves this problem.}{\seef{EnvCount}, \seef{GetEnv}} + +\input{dosex/ex13.tex} + +\procedure{Exec}{(const Path: pathstr; const ComLine: comstr)}{ +\var{Exec} executes the program in \var{Path}, with the options given by +\var{ComLine}. +After the program has terminated, the procedure returns. The Exit value of +the program can be consulted with the \var{DosExitCode} function. +}{Errors are reported in \var{DosError}.}{\seef{DosExitCode}} + +For an example, see \seef{DosExitCode} + +\functionl{FExpand}{Dos:FExpand}{(const path: pathstr)}{pathstr}{ +\var{FExpand} takes its argument and expands it to a complete filename, i.e. +a filename starting from the root directory of the current drive, prepended +with the drive-letter (under \dos). + +The resulting name is converted to uppercase on \dos systems. Under \linux, +the name is left as it is. (filenames are case sensitive under Unix) +}{\seep{FSplit}} + +\input{dosex/ex5.tex} + +\procedure{FindClose}{(Var F: SearchRec)}{ +\textbf{\linux only} +Under \linux, the \var{findfirst/findnext} calls have to be mimicked. +An internal table of file descriptors is kept. +When using different \var{searchrecs} at the same time, +the system may run out of file descriptors for directories. + +The \linux implementation of the \dos unit therefore keeps a table of open +directories, and when the table is full, closes one of the directories, and +reopens another. This system is adequate but slow if you use a lot of +\var{searchrecs}. + +So, to speed up the findfirst/findnext system, the \var{FindClose} call was +implemented. When you don't need a \var{searchrec} any more, you can tell +this to the \dos unit by issuing a \var{FindClose} call. The directory +which is kept open for this \var{searchrec} is then closed, and the table slot +freed. + +It is recommended to use the \linux call \var{Glob} when looking for files. +}{None.}{\seef{Glob}.} + +\procedure{FindFirst}{(const Path: pathstr; Attr: word; var F: SearchRec)}{ +\var{FindFirst} searches the file specified in \var{Path}, checks the +atrributes specified in \var{Attr}. It returns a \var{SearchRec} record for +further searching in \var{F}. + +\var{Path} can contain the wildcard characters \var{?} (matches any single +character) and \var{*} (matches 0 ore more arbitrary characters). In this +case \var{FindFirst} will return the first file which matches the specified +criteria. + +If \var{DosError} is different from zero, no file(s) matching the criteria +was(were) found.}{Errors are reported in DosError.}{\seep{FindNext}, +\seep{FindClose}} + +\input{dosex/ex7.tex} + +\procedure{FindNext}{(var f: searchRec)}{ +\var{FindNext} takes as an argument a \var{SearchRec} from a previous +\var{FindNext} call, or a \var{FindFirst} call, and tries to find another +file which matches the criteria, specified in the \var{FindFirst} call. + +If \var{DosError} is different from zero, no more files matching the +criteria were found.}{\var{DosError} is used to report errors.} +{\seep{FindFirst}, \seep{FindClose}} + +For an example, see \seep{FindFirst}. + +\functionl{FSearch}{Dos:FSearch}{(Path: pathstr; DirList: string)}{pathstr} +{\var{FSearch} searches the file \var{Path} in all directories listed in +\var{DirList}. The full name of the found file is returned. + +\var{DirList} must be a list of directories, separated by semi-colons (or +colons under \linux). + +When no file is found, an empty string is returned. +}{None.}{\seefl{FExpand}{Dos:FExpand}} + +\input{dosex/ex10.tex} + + + +\procedure{FSplit}{(path: pathstr; \\ var dir: dirstr; var name: namestr; + var ext: extstr)}{ +\var{FSplit} splits a full file name into 3 parts : A \var{Path}, a +\var{Name} and an extension (in \var{ext}.) + +Under \linux, the extension is taken to be all letters after the last dot +(.). +}{None.}{\seefl{FSearch}{Dos:FSearch}} + +\input{dosex/ex12.tex} + +\procedure{GetCBreak}{(var breakvalue: boolean)}{ +\var{GetCBreak} gets the status of CTRL-Break checking under \dos. +When \var{BreakValue} is \var{false}, then \dos only checks for the +CTRL-Break key-press when I/O is performed. When it is set to \var{True}, +then a check is done at every system call.}{Under Linux, this exists but is +not implemented, i.e. the call does nothing.}{\seep{SetCBreak}} + +\procedurel{GetDate}{Dos:GetDate}{(var year, month, mday, wday: word)}{ +\var{GetDate} returns the system's date. \var{Year} is a number in the range +1980..2099.\var{mday} is the day of the month, +\var{wday} is the day of the week, starting with Sunday as day 0.} +{None.}{\seepl{GetTime}{Dos:GetTime},\seep{SetDate}} + +\input{dosex/ex2.tex} + +\functionl{GetEnv}{Dos:GetEnv}{(EnvVar: String)}{String}{ +\var{Getenv} returns the value of the environment variable \var{EnvVar}. +Under \linux, case is important when looking for \var{EnvVar}. + +When there is no environment variable \var{EnvVar} defined, an empty +string is returned.}{None.}{\seef{EnvCount}, \seef{EnvStr}} + +\input{dosex/ex14.tex} + +\procedure{GetFAttr}{(var F; var Attr: word)}{ +\var{GetFAttr} returns the file attributes of the file-variable \var{f}. + \var{F} can be a untyped or typed file, or of type \var{Text}. \var{f} must +have been assigned, but not opened. The attributes can be examined with the +following constants : +\begin{itemize} +\item \var{ReadOnly = 01h} +\item \var{Hidden = 02h} +\item \var{SysFile = 04h} +\item \var{VolumeId = 08h} +\item \var{Directory = 10h} +\item \var{Archive = 20h} +\item \var{AnyFile = 3fh} +\end{itemize} +Under \linux, supported attributes are: +\begin{itemize} +\item \var{Directory} +\item \var{ReadOnly} if the current process doesn't have access to the file. +\item \var{Hidden} for files whose name starts with a dot \var{('.')}. +\end{itemize} +}{Errors are reported in \var{DosError}}{\seep{SetFAttr}} + +\input{dosex/ex8.tex} + +\procedure{GetFTime}{(var F; var Time: longint)}{ +\var{GetFTime} returns the modification time of a file. +This time is encoded and must be decoded with \var{UnPackTime}. +\var{F} must be a file type, which has been assigned, but not +opened.}{Errors are reported in \var{DosError}} +{\seep{SetFTime}, \seep{PackTime},\seep{UnPackTime}} + +\input{dosex/ex9.tex} + +\procedure{GetIntVec}{(IntNo: byte; var Vector: pointer)}{ +\var{GetIntVec} returns the address of interrupt vector +\var{IntNo}.}{None. Under \linux, this call exists bout isn't implemented, +i.e. it does nothing.}{\seep{SetIntVec}} + +\procedurel{GetTime}{Dos:GetTime}{(var hour, minute, second, sec100: word)}{ +\var{GetTime} returns the system's time. \var{Hour} is a on a 24-hour time +scale. \var{sec100} is in hundredth of a +second.}{None.}{\seepl{GetDate}{Dos:GetDate}, +\seep{SetTime}} + +\input{dosex/ex3.tex} + +\procedure{GetVerify}{(var verify: boolean)}{ +\var{GetVerify} returns the status of the verify flag under \dos. When +\var{Verify} is \var{True}, then \dos checks data which are written to disk, +by reading them after writing. If \var{Verify} is \var{False}, then data +written to disk are not verified.}{Under \linux, Verify is always +\var{True}.}{\seep{SetVerify}} + +\procedure{Intr}{(IntNo: byte; var Regs: registers)}{ +\var{Intr} executes a software interrupt number \var{IntNo} (must be between +0 and 255), with processor registers set to \var{Regs}. After the interrupt call +returned, the processor registers are saved in \var{Regs}.} +{Under \linux this call does nothing, because interrupts are managed by the +kernel. The only allowed interrupt is 80h, the kernel entry interrupt.} +{\seep{MSDos}, see the \linux unit.} + +\procedure{Keep}{(ExitCode: word)}{ +\var{Keep} terminates the program, but stays in memory. This is used for TSR +(Terminate Stay Resident) programs which catch some interrupt. +\var{ExitCode} is the same parameter as the \var{Halt} function takes.} +{Under \linux, this call does nothing.}{\seem{Halt}{}} + + +\procedure{MSDos}{(var regs: registers)}{ +\var{MSDos} executes an MS-\dos call (int 21h). This is the same as doing a +\var{Intr} call with an interrupt number of 21h.}{None.}{\seep{Intr}} + +\procedure{PackTime}{(var T: datetime; var P: longint)}{ +\var{UnPackTime} converts the date and time specified in \var{T} +to a packed-time format which can be fed to \var{SetFTime}.} +{None.} +{\seep{SetFTime}, \seep{FindFirst}, \seep{FindNext}, \seep{UnPackTime}} + +\input{dosex/ex4.tex} + +\procedure{SetCBreak}{(breakvalue: boolean)}{ +\var{SetCBreak} sets the status of CTRL-Break checking under \dos. +When \var{BreakValue} is \var{false}, then \dos only checks for the +CTRL-Break key-press when I/O is performed. When it is set to \var{True}, +then a check is done at every system call.}{Under Linux, this call exists +but is not implemented, i.e. it does nothing.}{\seep{GetCBreak}} + +\procedure{SetDate}{(year,month,day: word)}{ +\var{SetDate} sets the system's internal date. \var{Year} is a number +between 1980 and 2099.} +{On a \linux machine, this is not implemented (allthough a procedure +exists, it just doesn't do anything. The setting of the date is a +root-only privilege, and is hence not implemented.}{\seep{GetDate}, +\seep{SetTime}} + +\procedure{SetFAttr}{(var F; Attr: word)}{ +\var{SetFAttr} sets the file attributes of the file-variable \var{F}. + \var{F} can be a untyped or typed file, or of type \var{Text}. \var{F} must +have been assigned, but not opened. The attributes can be a sum of the +following constants: +\begin{itemize} +\item \var{ReadOnly = 01h} +\item \var{Hidden = 02h} +\item \var{SysFile = 04h} +\item \var{VolumeId = 08h} +\item \var{Directory = 10h} +\item \var{Archive = 20h} +\item \var{AnyFile = 3fh} +\end{itemize} +}{Errors are reported in \var{DosError}. + +Under \linux the call exists, but is not implemented, i.e. it does nothing.} +{\seep{GetFAttr}} + +\procedure{SetFTime}{(var F; Time: longint)}{ +\var{GetFTime} returns the modification time of a file, +this time is encoded and must be encoded with \var{PackTime}. +\var{F} must be a file type, which has been assigned, but not +opened.}{Errors are reported in \var{DosError}} +{\seep{GetFTime}, \seep{PackTime},\seep{UnPackTime}} + + +\procedure{SetIntVec}{(IntNo: byte; Vector: pointer)}{ +\var{SetIntVec} sets interrupt vector \var{IntNo} to \var{Vector}. +\var{Vector} should point to an interrupt procedure.}{Under \linux, this +call exists but is not implemented, the kernel manages all interrupts.} +{\seep{GetIntVec}} + +\procedure{SetTime}{(hour,minute,second,sec100: word)}{ +\var{SetTime} sets the system's internal clock. The \var{Hour} parameter is +on a 24-hour time scale.}{this call exists, but is not implemented on \linux, +as setting the time is a root-only privilege.} +{\seep{GetTime}, \seep{SetDate}} + + +\procedure{SetVerify}{(verify: boolean)}{ +\var{SetVerify} sets the status of the verify flag under \dos. When +\var{Verify} is \var{True}, then \dos checks data which are written to disk, +by reading them after writing. If \var{Verify} is \var{False}, then data +written to disk are not verified.}{Under \linux, Verify is always +\var{True}.}{\seep{SetVerify}} + +\Procedure{SwapVectors}{ +\var{SwapVectors} swaps the contents of the internal table of interrupt +vectors with the current contents of the interrupt vectors. + +This is called typically in before and after an \var{Exec} call. +}{Under \linux this call does nothing, as the interrupt vectors are +managed by the kernel.}{\seep{Exec}, \seep{SetIntVec}} + + +\procedure{UnPackTime}{(p: longint; var T: datetime)}{ +\var{UnPackTime} converts the file-modification time in \var{p} +to a \var{DateTime} record. The file-modification time can be +returned by \var{GetFTime}, \var{FindFirst} or \var{FindNext} calls.} +{None.} +{\seep{GetFTime}, \seep{FindFirst}, \seep{FindNext}, \seep{PackTime}} + +For an example, see \seep{PackTime}. + diff --git a/docs/dosex/Makefile b/docs/dosex/Makefile new file mode 100644 index 0000000000..31ddae67ca --- /dev/null +++ b/docs/dosex/Makefile @@ -0,0 +1,54 @@ +####################################################################### +# +# Makefile to compile all examples and convert them to LaTeX +# +####################################################################### + +# Compiler +PP=ppc386 + +# Unit directory +# UNITDIR=/usr/lib/ppc/0.99.0/linuxunits + + +# Any options you wish to pass. +PPOPTS= + +# Script to convert the programs to LaTeX examples which can be included. +PP2TEX=pp2tex + +# Script to collect all examples in 1 file. +MAKETEX=make1tex + +####################################################################### +# No need to edit after this line. +####################################################################### + +ifdef UNITDIR +PPOPTS:=$(PPOPTS) -Up$(UNITDIR); +endif + +.SUFFIXES: .pp .tex + +.PHONY: all tex clean + +OBJECTS=ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex11 ex12 ex13 ex14 \ +# ex15 ex16 + +TEXOBJECTS=$(addsuffix .tex, $(OBJECTS)) + +all : $(OBJECTS) + +tex : $(TEXOBJECTS) + +onetex : tex + $(MAKETEX) $(TEXOBJECTS) + +clean : + rm -f *.o *.s $(OBJECTS) $(TEXOBJECTS) + +$(OBJECTS): %: %.pp + $(PP) $(PPOPTS) $* + +$(TEXOBJECTS): %.tex: %.pp head.tex foot.tex + $(PP2TEX) $* diff --git a/docs/dosex/README b/docs/dosex/README new file mode 100644 index 0000000000..f64c1d5659 --- /dev/null +++ b/docs/dosex/README @@ -0,0 +1,18 @@ +These are the example programs that appear in the FPC documentation. + +Units guide, DOS unit : + +ex1.pp contains an example of the DosVersion function. +ex2.pp contains an example of the GetDate function. +ex3.pp contains an example of the GetTime function. +ex4.pp contains an example of the PackTime and UnPackTime functions. +ex5.pp contains an example of the Exec and DosExitCode function. +ex6.pp contains an example of the DiskSize and DiskFree function. +ex7.pp contains an example of the FindFirst and FindNext function. +ex8.pp contains an example of the GetFAttr function. +ex9.pp contains an example of the GetFTime function. +ex10.pp contains an example of the FSearch function. +ex11.pp contains an example of the FExpand function. +ex12.pp contains an example of the FSplit function. +ex13.pp contains an example of the EnvCount and EnvStr function. +ex14.pp contains an example of the GetEnv function. diff --git a/docs/dosex/ex1.pp b/docs/dosex/ex1.pp new file mode 100644 index 0000000000..5e146cc233 --- /dev/null +++ b/docs/dosex/ex1.pp @@ -0,0 +1,18 @@ +Program Example1; +uses Dos; + +{ Program to demonstrate the DosVersion function. } + +var + OS : string[32]; + Version : word; +begin +{$IFDEF LINUX} + OS:='Linux'; +{$ENDIF} +{$IFDEF DOS} + OS:='Dos'; +{$ENDIF} + Version:=DosVersion; + WriteLn('Current ',OS,' version is ',Lo(Version),'.',Hi(Version)); +end. diff --git a/docs/dosex/ex10.pp b/docs/dosex/ex10.pp new file mode 100644 index 0000000000..50fc4595f2 --- /dev/null +++ b/docs/dosex/ex10.pp @@ -0,0 +1,14 @@ +Program Example10; +uses Dos; + +{ Program to demonstrate the FSearch function. } + +var + s : string; +begin + s:=FSearch(ParamStr(1),GetEnv('PATH')); + if s='' then + WriteLn(ParamStr(1),' not Found in PATH') + else + Writeln(ParamStr(1),' Found in PATH at ',s); +end. diff --git a/docs/dosex/ex11.pp b/docs/dosex/ex11.pp new file mode 100644 index 0000000000..681ce1e1c8 --- /dev/null +++ b/docs/dosex/ex11.pp @@ -0,0 +1,8 @@ +Program Example11; +uses Dos; + +{ Program to demonstrate the FExpand function. } + +begin + WriteLn('Expanded Name of this program is ',FExpand(ParamStr(0))); +end. diff --git a/docs/dosex/ex12.pp b/docs/dosex/ex12.pp new file mode 100644 index 0000000000..403fc140a0 --- /dev/null +++ b/docs/dosex/ex12.pp @@ -0,0 +1,14 @@ +Program Example12; +uses Dos; + +{ Program to demonstrate the FSplit function. } + +var + Path,Name,Ext : string; +begin + FSplit(ParamStr(1),Path,Name,Ext); + WriteLn('Splitted ',ParamStr(1),' in:'); + WriteLn('Path : ',Path); + WriteLn('Name : ',Name); + WriteLn('Extension: ',Ext); +end. diff --git a/docs/dosex/ex13.pp b/docs/dosex/ex13.pp new file mode 100644 index 0000000000..a393af523f --- /dev/null +++ b/docs/dosex/ex13.pp @@ -0,0 +1,12 @@ +Program Example13; +uses Dos; + +{ Program to demonstrate the EnvCount and EnvStr function. } + +var + i : Longint; +begin + WriteLn('Current Environment is:'); + for i:=1to EnvCount do + WriteLn(EnvStr(i)); +end. diff --git a/docs/dosex/ex14.pp b/docs/dosex/ex14.pp new file mode 100644 index 0000000000..abdf2a2530 --- /dev/null +++ b/docs/dosex/ex14.pp @@ -0,0 +1,8 @@ +Program Example14; +uses Dos; + +{ Program to demonstrate the GetEnv function. } + +begin + WriteLn('Current PATH is ',GetEnv('PATH')); +end. diff --git a/docs/dosex/ex2.pp b/docs/dosex/ex2.pp new file mode 100644 index 0000000000..02f237f201 --- /dev/null +++ b/docs/dosex/ex2.pp @@ -0,0 +1,16 @@ +Program Example2; +uses Dos; + +{ Program to demonstrate the GetDate function. } + +const + DayStr:array[0..6] of string[3]=('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); + MonthStr:array[1..12] of string[3]=('Jan','Feb','Mar','Apr','May','Jun', + 'Jul','Aug','Sep','Oct','Nov','Dec'); +var + Year,Month,Day,WDay : word; +begin + GetDate(Year,Month,Day,WDay); + WriteLn('Current date'); + WriteLn(DayStr[WDay],', ',Day,' ',MonthStr[Month],' ',Year,'.'); +end. diff --git a/docs/dosex/ex3.pp b/docs/dosex/ex3.pp new file mode 100644 index 0000000000..ef0353d304 --- /dev/null +++ b/docs/dosex/ex3.pp @@ -0,0 +1,23 @@ +Program Example3; +uses Dos; + +{ Program to demonstrate the GetTime function. } + +Function L0(w:word):string; +var + s : string; +begin + Str(w,s); + if w<10 then + L0:='0'+s + else + L0:=s; +end; + +var + Hour,Min,Sec,HSec : word; +begin + GetTime(Hour,Min,Sec,HSec); + WriteLn('Current time'); + WriteLn(L0(Hour),':',L0(Min),':',L0(Sec)); +end. diff --git a/docs/dosex/ex4.pp b/docs/dosex/ex4.pp new file mode 100644 index 0000000000..f900b69635 --- /dev/null +++ b/docs/dosex/ex4.pp @@ -0,0 +1,32 @@ +Program Example4; +uses Dos; + +{ Program to demonstrate the PackTime and UnPackTime functions. } + +var + DT : DateTime; + Time : longint; +begin + with DT do + begin + Year:=1998; + Month:=11; + Day:=11; + Hour:=11; + Min:=11; + Sec:=11; + end; + PackTime(DT,Time); + WriteLn('Packed Time : ',Time); + UnPackTime(Time,DT); + WriteLn('Unpacked Again:'); + with DT do + begin + WriteLn('Year ',Year); + WriteLn('Month ',Month); + WriteLn('Day ',Day); + WriteLn('Hour ',Hour); + WriteLn('Min ',Min); + WriteLn('Sec ',Sec); + end; +end. diff --git a/docs/dosex/ex5.pp b/docs/dosex/ex5.pp new file mode 100644 index 0000000000..4e477d5158 --- /dev/null +++ b/docs/dosex/ex5.pp @@ -0,0 +1,15 @@ +Program Example5; +uses Dos; + +{ Program to demonstrate the Exec and DosExitCode function. } + +begin +{$IFDEF LINUX} + WriteLn('Executing /bin/ls -la'); + Exec('/bin/ls','-la'); +{$ELSE} + WriteLn('Executing Dir'); + Exec(GetEnv('COMSPEC'),'/C dir'); +{$ENDIF} + WriteLn('Program returned with ExitCode ',DosExitCode); +end. diff --git a/docs/dosex/ex6.pp b/docs/dosex/ex6.pp new file mode 100644 index 0000000000..190577dcfb --- /dev/null +++ b/docs/dosex/ex6.pp @@ -0,0 +1,9 @@ +Program Example6; +uses Dos; + +{ Program to demonstrate the DiskSize and DiskFree function. } + +begin + WriteLn('This partition size has ',DiskSize(0),' bytes'); + WriteLn('Currently ',DiskFree(0),' bytes are free'); +end. diff --git a/docs/dosex/ex7.pp b/docs/dosex/ex7.pp new file mode 100644 index 0000000000..cb21ffae2b --- /dev/null +++ b/docs/dosex/ex7.pp @@ -0,0 +1,17 @@ +Program Example7; +uses Dos; + +{ Program to demonstrate the FindFirst and FindNext function. } + +var + Dir : SearchRec; +begin + FindFirst('*.*',$20,Dir); + WriteLn('FileName'+Space(32),'FileSize':9); + while (DosError=0) do + begin + Writeln(Dir.Name+Space(40-Length(Dir.Name)),Dir.Size:9); + FindNext(Dir); + end; + FindClose(Dir); +end. diff --git a/docs/dosex/ex8.pp b/docs/dosex/ex8.pp new file mode 100644 index 0000000000..03b4d70b6b --- /dev/null +++ b/docs/dosex/ex8.pp @@ -0,0 +1,18 @@ +Program Example8; +uses Dos; + +{ Program to demonstrate the GetFAttr function. } + +var + Attr : Word; + f : File; +begin + Assign(f,ParamStr(1)); + GetFAttr(f,Attr); + WriteLn('File ',ParamStr(1),' has attribute ',Attr); + if (Attr and $20)<>0 then WriteLn('- Archive'); + if (Attr and $10)<>0 then WriteLn('- Directory'); + if (Attr and $4)<>0 then WriteLn('- Read-Only'); + if (Attr and $2)<>0 then WriteLn('- System'); + if (Attr and $1)<>0 then WriteLn('- Hidden'); +end. diff --git a/docs/dosex/ex9.pp b/docs/dosex/ex9.pp new file mode 100644 index 0000000000..7984e97a3c --- /dev/null +++ b/docs/dosex/ex9.pp @@ -0,0 +1,30 @@ +Program Example9; +uses Dos; + +{ Program to demonstrate the GetFTime function. } + +Function L0(w:word):string; +var + s : string; +begin + Str(w,s); + if w<10 then + L0:='0'+s + else + L0:=s; +end; + +var + f : File; + Time : Longint; + DT : DateTime; +begin + Assign(f,ParamStr(1)); + Reset(f); + GetFTime(f,Time); + Close(f); + UnPackTime(Time,DT); + Write ('File ',ParamStr(1),' is last modified on '); + Writeln (L0(DT.Month),'-',L0(DT.Day),'-',DT.Year, + ' at ',L0(DT.Hour),':',L0(DT.Min)); +end. diff --git a/docs/dosex/foot.tex b/docs/dosex/foot.tex new file mode 100644 index 0000000000..83788a402a --- /dev/null +++ b/docs/dosex/foot.tex @@ -0,0 +1,2 @@ +\end{verbatim} +\end{FPKList} \ No newline at end of file diff --git a/docs/dosex/head.tex b/docs/dosex/head.tex new file mode 100644 index 0000000000..b2ed5b6603 --- /dev/null +++ b/docs/dosex/head.tex @@ -0,0 +1,3 @@ +\begin{FPKList} +\item[Example] +\begin{verbatim} diff --git a/docs/dosex/newex b/docs/dosex/newex new file mode 100644 index 0000000000..cd2f06fac0 --- /dev/null +++ b/docs/dosex/newex @@ -0,0 +1,9 @@ +#!/bin/sh +if [ -e ex${1}.pp ]; then + mv ex${1}.pp ex${1}.pp.orig +fi +sed -e s/Example/Example$1/ -e s/\\\*\\\*\\\*/$2/ ex${1}.pp +echo "ex${1}.pp contains an example of the $2 function." >>README +mcedit ex${1}.pp +ppc386 ex${1}.pp && ex${1} +rm ex${1}.o diff --git a/docs/dosex/pp2tex b/docs/dosex/pp2tex new file mode 100644 index 0000000000..3a5cd6a448 --- /dev/null +++ b/docs/dosex/pp2tex @@ -0,0 +1,5 @@ +#!/bin/sh +# Simply paste a header and footer to the program. +cat head.tex > $1.tex +cat $1.pp >> $1.tex +cat foot.tex >> $1.tex diff --git a/docs/dosex/template.pp b/docs/dosex/template.pp new file mode 100644 index 0000000000..101cff459f --- /dev/null +++ b/docs/dosex/template.pp @@ -0,0 +1,7 @@ +Program Example; +uses Dos; + +{ Program to demonstrate the *** function. } + +begin +end. diff --git a/docs/foot.sed b/docs/foot.sed new file mode 100644 index 0000000000..adea38a025 --- /dev/null +++ b/docs/foot.sed @@ -0,0 +1 @@ +/^.$/d diff --git a/docs/fpctoc.html b/docs/fpctoc.html new file mode 100644 index 0000000000..c7d9b42e4c --- /dev/null +++ b/docs/fpctoc.html @@ -0,0 +1,18 @@ + +Free Pascal Manuals : Table of contents + +

Free Pascal manuals

+

Table of contents

+
+

Manuals

+ +

+


+ + diff --git a/docs/fpk-html.tex b/docs/fpk-html.tex new file mode 100644 index 0000000000..7fdfcfa727 --- /dev/null +++ b/docs/fpk-html.tex @@ -0,0 +1,119 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +% Dummy +\newenvironment{FPKList}{\begin{description}}{\end{description}} +\newcommand{\functionl}[7]{ +\subsection{#1} +\label{fu:#2} +\index{#1} +\subsubsection*{Declaration:} +\texttt {Function #1 #3 : #4;} +\subsubsection*{Description:} +#5 +\subsubsection*{Errors:} +#6 +\subsubsection*{See also:} +#7 +} +\newcommand{\procedurel}[6]{ +\subsection{#1} +\label{pro:#2} +\index{#1} +\subsubsection*{Declaration:} +\texttt {Procedure #1 #3 ;} +\subsubsection*{Description:} +#4 +\subsubsection*{Errors:} +#5 +\subsubsection*{See also:} +#6 +} +\newcommand{\seefl}[2]{ +\htmlref{#1}{fu:#2} +} +\newcommand{\seepl}[2]{ +\htmlref{#1}{pro:#2} +} +% +% Now the ones without label. +% +\newcommand{\seef}[1]{\seefl{#1}{#1}} +\newcommand{\seep}[1]{\seepl{#1}{#1}} +% +\newcommand{\seet}[1]{ +\htmlref{#1}{sec:types} +} +\newcommand{\seem}[2] {\texttt{#1} (#2) } +\newcommand{\var}[1]{\texttt {#1}} +\newcommand{\file}[1]{\textsf {#1}} +% +% procedures without args +% +\newcommand{\Procedurel}[5]{\procedurel{#1}{#2}{}{#3}{#4}{#5}} +\newcommand{\Functionl}[6]{\functionl{#1}{#2}{}{#3}{#4}{#5}{#6}} +% +% Procedures without labels. +% +\newcommand{\procedure}[5]{\procedurel{#1}{#1}{#2}{#3}{#4}{#5}} +\newcommand{\function}[6]{\functionl{#1}{#1}{#2}{#3}{#4}{#5}{#6}} +\newcommand{\Procedure}[4]{\procedure{#1}{}{#2}{#3}{#4}} +\newcommand{\Function}[5]{\function{#1}{}{#2}{#3}{#4}{#5}} +\newcommand{\linux}{\textsc{LinuX} } +\newcommand{\dos} {\textsc{dos} } +\newcommand{\msdos}{\textsc{ms-dos} } +\newcommand{\ostwo}{\textsc{os/2} } +\newcommand{\windowsnt}{\textsc{WindowsNT} } +\newcommand{\docdescription}[1]{} +\newcommand{\docversion}[1]{} +\newcommand{\unitdescription}[1]{} +\newcommand{\unitversion}[1]{} +\newcommand{\fpk}{Free Pascal } +\newcommand{\gnu}{gnu } +% +% Useful references. +% +\newcommand{\progref}{\htmladdnormallink{Programmer's guide}{../prog/prog.html}\ } +\newcommand{\refref}{\htmladdnormallink{Reference guide}{../ref/ref.html}\ } +\newcommand{\userref}{\htmladdnormallink{Users' guide}{../user/user.html}\ } +\newcommand{\seecrt}{\htmladdnormallink{CRT}{../crt/crt.html}} +\newcommand{\seelinux}{\htmladdnormallink{Linux}{../linux/linux.html}} +\newcommand{\seestrings}{\htmladdnormallink{strings}{../strings/strings.html}} +\newcommand{\seedos}{\htmladdnormallink{DOS}{../dos/dos.html}} +\newcommand{\seegetopts}{\htmladdnormallink{getopts}{../getopts/getopts.html}} +\newcommand{\seeobjects}{\htmladdnormallink{objects}{../objects/objects.html}} +\newcommand{\seegraph}{\htmladdnormallink{graph}{../graph/graph.html}} +\newcommand{\seeprinter}{\htmladdnormallink{printer}{../printer/printer.html}} +\newcommand{\seego}{\htmladdnormallink{GO32}{../go32/go32.html}} +% +% Nice environments +% +% For Code examples (complete programs only) +\newenvironment{CodEx}{}{} +% For Tables. +\newenvironment{FPKtable}[2]{\begin{table}\caption{#2}\begin{center}\begin{tabular}{#1}}{\end{tabular}\end{center}\end{table}} +% The same, but with label in third argument (tab:#3) +\newenvironment{FPKltable}[3]{\begin{table}\caption{#2}\label{tab:#3}\begin{center}\begin{tabular}{#1}}{\end{tabular}\end{center}\end{table}} +% +% Commands to reference these things. +% +\newcommand{\seet}[1]{table (\ref{tab:#1}) } +\newcommand{\seec}[1]{chapter (\ref{ch:#1}) } +\newcommand{\sees}[1]{section (\ref{se:#1}) } diff --git a/docs/fpk.perl b/docs/fpk.perl new file mode 100644 index 0000000000..30a7405db7 --- /dev/null +++ b/docs/fpk.perl @@ -0,0 +1,107 @@ +# FPK.PERL script. Accompagnies fpk.sty +# by Michael Van Canneyt +# December 1996 +# +# Extension to LaTeX2HTML, to translate fpk style commands. +# + +package main; + +$fpkresult=''; + +sub FPKinternalproc{ +local ($name, $decl, $desc, $errors, $seealso) = @_ ; +local ($result) = ''; + + $result = "

$name

\n

\n" ; + $result .= "

Declaration:

\n

\n$decl\n

\n" ; + $result .= "

Description:

\n

\n$desc\n

\n" ; + $result .= "

Errors:

\n

\n$errors\n

\n" ; + $result .= "

See Also:

\n

\n$seealso\n

\n" ; + $result ; +} + +sub do_cmd_procedure +{ + $fpkresult = "

$_[0]

\n

\n" ; + $fpkresult .= "

Declaration:

\n

\nProcedure $_[0] $_[1]\n

\n" ; + $fpkresult .= "

Description:

\n

\n$_[2]\n

\n" ; + $fpkresult .= "

Errors:

\n

\n$_[3]\n

\n" ; + $fpkresult .= "

See Also:

\n

\n$_[4]\n

\n" ; + $fpkresult ; +} + +sub do_cmd_Procedure +{ + $fpkresult = "

$_[0]

\n

\n" ; + $fpkresult .= "

Declaration:

\n

\nProcedure $_[0];\n

\n" ; + $fpkresult .= "

Description:

\n

\n$_[1]\n

\n" ; + $fpkresult .= "

Errors:

\n

\n$_[2]\n

\n" ; + $fpkresult .= "

See Also:

\n

\n$_[3]\n

\n" ; + $fpkresult ; +} + +sub do_cmd_Function +{ + $fpkresult = "

$_[0]

\n

\n" ; + $fpkresult .= "

Declaration:

\n

\nFunction $_[0] : $_[1]\n

\n" ; + $fpkresult .= "

Description:

\n

\n$_[2]\n

\n" ; + $fpkresult .= "

Errors:

\n

\n$_[3]\n

\n" ; + $fpkresult .= "

See Also:

\n

\n$_[4]\n

\n" ; + $fpkresult ; +} + +sub do_cmd_function +{ + $fpkresult = "

$_[0]

\n

\n" ; + $fpkresult .= "

Declaration:

\n

\nFunction $_[0] $_[1] : $_[2]\n

\n" ; + $fpkresult .= "

Description:

\n

\n$_[3]\n

\n" ; + $fpkresult .= "

Errors:

\n

\n$_[4]\n

\n" ; + $fpkresult .= "

See Also:

\n

\n$_[5]\n

\n" ; + $fpkresult ; +} + +sub do_cmd_var{ +local ($_) = @_; +"$_" ; +} + +sub do_cmd_linux{ +"LinuX" ; +} + +sub do_cmd_dos{ +"DOS" ; +} + +sub do_cmd_msdos{ +"MS-DOS" ; +} + +sub do_cmd_windowsnt{ +"Windows NT" ; +} + +sub do_cmd_ostwo{ +"OS/2" ; +} + +sub do_cmd_seep{ +"" ; +} + +sub do_cmd_seef{ +"" ; +} + +sub do_cmd_seem{ +"" ; +} + +# For testing purposes +# print do_cmd_procedure ("Proc1","decl1","desc1","err1","see1"); +# print do_cmd_Procedure ("Proc2","desc2","err2","see2"); +# print do_cmd_function ("Fun1","fdecl1","ftype1","fdesc1","ferr1","fsee1"); +# print do_cmd_Function ("Fun2","ftype2","fdesc2","ferr2","fsee2"); + +1; # required... \ No newline at end of file diff --git a/docs/fpk.sty b/docs/fpk.sty new file mode 100644 index 0000000000..7cb07aaa7d --- /dev/null +++ b/docs/fpk.sty @@ -0,0 +1,188 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\ProvidesPackage{fpk}[1996/12/09] +\NeedsTeXFormat{LaTeX2e} +\ExecuteOptions{titlepage} +% First, all definitions for latex only. +\newcommand{\docdescription}[1]{\def\@FPKDescription{#1}} +\gdef\@FPKDescription{}% +\newcommand{\docversion}[1]{\def\@FPKVersion{#1}} +\gdef\@FPKVersion{}% +% For backwards compatibility +\newcommand{\unitdescription}[1]{\def\@FPKDescription{#1}} +\newcommand{\unitversion}[1]{\def\@FPKVersion{#1}} +\renewcommand\maketitle{\begin{titlepage}% + \let\footnotesize\small + \let\footnoterule\relax + \null\vfil + \vskip 4cm% + {\noindent\raggedright\Large\@title\\}% + \noindent \rule{\linewidth}{1.5mm}\\% + {\raggedleft\large% + \begin{tabular}[t]{r}% + \@FPKDescription \\ + \@FPKVersion \\ + \@date + \end{tabular}\par}% + \vskip 5cm% + {\noindent \large \textsf{\@author} \\% + \rule{\linewidth}{0.5mm}} + \@thanks + \vfil\null + \end{titlepage}% + \setcounter{footnote}{0}% + \let\thanks\relax\let\maketitle\relax + \gdef\@thanks{}\gdef\@author{}\gdef\@title{}} + % end of \maketitle +% For the \procedure and \function commands, we don't want heading numbers. +\setcounter{secnumdepth}{1} +% redefine the subsection command to leave less space, +%and to use sans serif +\renewcommand\subsection{\@startsection% +{subsection}% +{2}% +{\z@}% +{-4.25ex\@plus -1ex \@minus -.2ex}% +{1pt}% +{\normalfont\large\sffamily\bfseries}} +% Now, Let's define the \procedure and \function commands. +\newcommand{\FPKlabel}[1]{% +\raggedleft\makebox[0pt][r]{\textsf{#1:}} +} +\newenvironment{FPKList} +{\begin{list}{}{% +\renewcommand{\makelabel}[1]{\FPKlabel{##1}\hfil\relax} + \setlength{\labelwidth}{0pt}% + \setlength{\leftmargin}{0pt}}% + \setlength{\labelsep}{0pt}% +} +{\end{list}} +% +% define a version of \procedure and \function +% which allows you to give a label. +% +\newcommand{\functionl}[7]{ +\subsection{#1} +\raisebox{1ex}{\rule{\linewidth}{0.5mm}} +\label{fu:#2} +\index{#1} +\begin{FPKList} +\item[Declaration] +\texttt {Function #1 #3 : #4;} +\item[Description] +#5 +\item[Errors] +#6 +\item[See also] +#7 +\end{FPKList} +} +\newcommand{\procedurel}[6]{ +\subsection{#1} +\raisebox{1ex}{\rule{\linewidth}{0.5mm}} +\label{pro:#2} +\index{#1} +\begin{FPKList} +\item[Declaration] +\texttt {Procedure #1 #3;} +\item[Description] +#4 +\item[Errors] +#5 +\item[See also] +#6 +\end{FPKList} +} +% define a capital version, +% for function/command which has no options passed to it. +\newcommand{\Functionl}[6]{\functionl{#1}{#2}{}{#3}{#4}{#5}{#6}} +\newcommand{\Procedurel}[5]{\procedurel{#1}{#2}{}{#3}{#4}{#5}} +% +% These versions take the function name as the label. +% +\newcommand{\function}[6]{\functionl{#1}{#1}{#2}{#3}{#4}{#5}{#6}} +\newcommand{\procedure}[5]{\procedurel{#1}{#1}{#2}{#3}{#4}{#5}} +% define a capital version, +% for function/command which has no options passed to it. +\newcommand{\Function}[5]{\function{#1}{}{#2}{#3}{#4}{#5}} +\newcommand{\Procedure}[4]{\procedure{#1}{}{#2}{#3}{#4}} +% Now the referencing commands. +% +% First, the ones with alternate label (second argument} +% +\newcommand{\seefl}[2]{ +\textsf{#1} (\pageref{fu:#2})} +\newcommand{\seepl}[2]{ +\textsf{#1} (\pageref{pro:#2})} +% +% Now the ones with label. +% +\newcommand{\seef}[1]{\seefl{#1}{#1}} +\newcommand{\seep}[1]{\seepl{#1}{#1}} +% +% man page references don't need labels. +% +\newcommand{\seem}[2]{\texttt{#1} (#2) } +% +% for easy typesetting of variables. +% +\newcommand{\var}[1]{\texttt {#1}} +\newcommand{\file}[1]{\textsf {#1}} +% +% Useful references. +% +\newcommand{\progref}{\htmladdnormallink{Programmers' guide}{../prog/prog.html}\ } +\newcommand{\refref}{\htmladdnormallink{Reference guide}{../ref/ref.html}\ } +\newcommand{\userref}{\htmladdnormallink{Users' guide}{../user/user.html}\ } +\newcommand{\seecrt}{\htmladdnormallink{CRT}{../crt/crt.html}} +\newcommand{\seelinux}{\htmladdnormallink{Linux}{../linux/linux.html}} +\newcommand{\seestrings}{\htmladdnormallink{strings}{../strings/strings.html}} +\newcommand{\seedos}{\htmladdnormallink{DOS}{../dos/dos.html}} +\newcommand{\seegetopts}{\htmladdnormallink{getopts}{../getopts/getopts.html}} +\newcommand{\seeobjects}{\htmladdnormallink{objects}{../objects/objects.html}} +\newcommand{\seegraph}{\htmladdnormallink{graph}{../graph/graph.html}} +\newcommand{\seeprinter}{\htmladdnormallink{printer}{../printer/printer.html}} +\newcommand{\seego}{\htmladdnormallink{GO32}{../go32/go32.html}} +% +% Nice environments +% +% For Code examples (complete programs only) +\newenvironment{CodEx}{}{} +% For Tables. +\newenvironment{FPKtable}[2]{\begin{table}\caption{#2}\begin{center}\begin{tabular}{#1}}{\end{tabular}\end{center}\end{table}} +% The same, but with label in third argument (tab:#3) +\newenvironment{FPKltable}[3]{\begin{table}\caption{#2}\label{tab:#3}\begin{center}\begin{tabular}{#1}}{\end{tabular}\end{center}\end{table}} +% +% Commands to reference these things. +% +\newcommand{\seet}[1]{table (\ref{tab:#1}) } +% +% some OSes +% +\newcommand{\linux}{\textsc{linux}\ } +\newcommand{\dos} {\textsc{dos}\ } +\newcommand{\msdos}{\textsc{ms-dos}\ } +\newcommand{\ostwo}{\textsc{os/2}\ } +\newcommand{\windows}{\textsc{Windows}\ } +\newcommand{\windowsnt}{\textsc{WindowsNT}\ } +\newcommand{\fpk}{Free Pascal\ } +\newcommand{\gnu}{\textsc{gnu}\ } +% end of fpk.sty diff --git a/docs/fpk.sty.doc b/docs/fpk.sty.doc new file mode 100644 index 0000000000..9601ea0977 --- /dev/null +++ b/docs/fpk.sty.doc @@ -0,0 +1,66 @@ +fpk.sty defines the following: + +\procedure{name}{args}{desc}{errs}{seealso} +\Procedure{name}{desc}{errs}{seealso} +\function{name}{args}{return-type}{desc}{errs}{seealso} +\Function{name}{return-type}{desc}{errs}{seealso} + +here is: +name : the name of the function/procedure +args : the (optional) arguments. type them between (), the sty doesn't add +them. +desc : the description of what it does. This can be very long. +errs : possible errors, and what the function then does. +seealso : info about related commands. + +Each procedure/punction call produces a subsection. it adds a label +'pro:name' or 'fu:name' and an index entry 'name'. +then it gives the declaration as in the pascal file, +it adds the description, the errors and see also, all in a list. +the Capital letter commands are shorthands for if the function has no +arguments (such as WhereX or so in crt.) + +So the above \function would produce: + +name (format of subsection) +------------------------------------ + +Declaration: name args : return-type + +Description : desc + +Errors : errs + +See also : seealso + +The style redifines the \maketitle command, and adds a +\description{Your description goes here} +\version{Your version goes here} +command, which produces something on the titlepage. (see the docs for +examples) + +it also defines +\var{arg} +which typesets in \texttt its argument + +\seef{name} +makes a cross reference (pageref) to function name (be careful about capitals). +\seep{name} +makes a cross reference (pageref) to procedure name.. +\seem{man}{sec} +produces a reference to a UNIX man page. as in : +man (sec) + +For nice typesetting it defines also \fpk, which niicely formats the name of +the compiler. + +Then it defines also +\linux +\dos +\msdos +\ostwo +\windowsnt +commands, which just typeset in small caps the name of the OS's... + +I think that's about it. +Michael. diff --git a/docs/fpkman.sty b/docs/fpkman.sty new file mode 100644 index 0000000000..d2a7ec784d --- /dev/null +++ b/docs/fpkman.sty @@ -0,0 +1,156 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\ProvidesPackage{fpkman}[1997/06/25] +\NeedsTeXFormat{LaTeX2e} +\ExecuteOptions{titlepage} +% First, all definitions for latex only. +\newcommand{\docdescription}[1]{\def\@FPKDescription{#1}} +\gdef\@FPKDescription{}% +\newcommand{\docversion}[1]{\def\@FPKVersion{#1}} +\gdef\@FPKVersion{}% +% For backwards compatibility +\newcommand{\unitdescription}[1]{\def\@FPKDescription{#1}} +\newcommand{\unitversion}[1]{\def\@FPKVersion{#1}} +\renewcommand\maketitle{\begin{titlepage}% + \let\footnotesize\small + \let\footnoterule\relax + \null\vfil + \vskip 4cm% + {\noindent\raggedright\Large\@title\\}% + \noindent \rule{\linewidth}{1.5mm}\\% + {\raggedleft\large% + \begin{tabular}[t]{r}% + \@FPKDescription \\ + \@FPKVersion \\ + \@date + \end{tabular}\par}% + \vskip 5cm% + {\noindent \large \textsf{\@author} \\% + \rule{\linewidth}{0.5mm}} + \@thanks + \vfil\null + \end{titlepage}% + \setcounter{footnote}{0}% + \let\thanks\relax\let\maketitle\relax + \gdef\@thanks{}\gdef\@author{}\gdef\@title{}} + % end of \maketitle +% For the \procedure and \function commands, we don't want heading numbers. +\setcounter{secnumdepth}{1} +% redefine the subsection command to leave less space, +%and to use sans serif +% Now, Let's define the \procedure and \function commands. +\newcommand{\FPKlabel}[1]{% +\raggedleft\makebox[0pt][r]{\textsf{#1:}} +} +\newenvironment{FPKList} +{\begin{list}{}{% +\renewcommand{\makelabel}[1]{\FPKlabel{##1}\hfil\relax} + \setlength{\labelwidth}{0pt}% + \setlength{\leftmargin}{0pt}}% + \setlength{\labelsep}{0pt}% +} +{\end{list}} +\newcommand{\function}[6]{ +\subsection{#1} +\raisebox{1ex}{\rule{\linewidth}{0.5mm}} +\label{fu:#1} +\index{#1} +\begin{FPKList} +\item[Declaration] +\texttt {Function #1 #2 : #3;} +\item[Description] +#4 +\item[Errors] +#5 +\item[See also] +#6 +\end{FPKList} +} +\newcommand{\procedure}[5]{ +\subsection{#1} +\raisebox{1ex}{\rule{\linewidth}{0.5mm}} +\label{pro:#1} +\index{#1} +\begin{FPKList} +\item[Declaration] +\texttt {Function #1 #2;} +\item[Description] +#3 +\item[Errors] +#4 +\item[See also] +#5 +\end{FPKList} +} +% define a capital version, +% for function/command which has no options passed to it. +\newcommand{\Function}[5]{\function{#1}{}{#2}{#3}{#4}{#5}} +\newcommand{\Procedure}[4]{\procedure{#1}{}{#2}{#3}{#4}} +% Now the referencing commands. +\newcommand{\seef}[1]{ +\textsf{#1} (\pageref{fu:#1})} +\newcommand{\seep}[1]{ +\textsf{#1} (\pageref{pro:#1})} +% man page references... +\newcommand{\seem}[2] {#1(#2) } +% for easy typesetting of variables and files. +\newcommand{\var}[1]{\texttt {#1}} +\newcommand{\file}[1]{\textsf {#1}} +% +% Useful references. +% +\newcommand{\progref}{\htmladdnormallink{Programmer's guide}{../prog/prog.html}\ } +\newcommand{\refref}{\htmladdnormallink{Reference guide}{../ref/ref.html}\ } +\newcommand{\userref}{\htmladdnormallink{Users' guide}{../user/user.html}\ } +\newcommand{\seecrt}{\htmladdnormallink{CRT}{../crt/crt.html}} +\newcommand{\seelinux}{\htmladdnormallink{Linux}{../linux/linux.html}} +\newcommand{\seestrings}{\htmladdnormallink{strings}{../strings/strings.html}} +\newcommand{\seedos}{\htmladdnormallink{DOS}{../dos/dos.html}} +\newcommand{\seegetopts}{\htmladdnormallink{getopts}{../getopts/getopts.html}} +\newcommand{\seeobjects}{\htmladdnormallink{objects}{../objects/objects.html}} +\newcommand{\seegraph}{\htmladdnormallink{graph}{../graph/graph.html}} +\newcommand{\seeprinter}{\htmladdnormallink{printer}{../printer/printer.html}} +\newcommand{\seego}{\htmladdnormallink{GO32}{../go32/go32.html}} +\newcommand{\seec}[1]{chapter \ref{ch:#1}} +\newcommand{\sees}[1]{section \ref{se:#1}} +% +% Nice environments +% +% For Code examples (complete programs only) +\newenvironment{CodEx}{}{} +% For Tables. +\newenvironment{FPKtable}[2]{\begin{table}\caption{#2}\begin{center}\begin{tabular}{#1}}{\end{tabular}\end{center}\end{table}} +% The same, but with label in third argument (tab:#3) +\newenvironment{FPKltable}[3]{\begin{table}\caption{#2}\label{tab:#3}\begin{center}\begin{tabular}{#1}}{\end{tabular}\end{center}\end{table}} +% +% Commands to reference these things. +% +\newcommand{\seet}[1]{table (\ref{tab:#1}) } +% some OSes +\newcommand{\linux}{\textsc{linux}\ } +\newcommand{\dos} {\textsc{dos}\ } +\newcommand{\msdos}{\textsc{ms-dos}\ } +\newcommand{\ostwo}{\textsc{os/2}\ } +\newcommand{\windowsnt}{\textsc{WindowsNT}\ } +\newcommand{\windows}{\textsc{Windows}\ } +\newcommand{\fpk}{Free Pascal\ } +\newcommand{\gnu}{\textsc{gnu}\ } +% end of fpkman.sty diff --git a/docs/getopts.tex b/docs/getopts.tex new file mode 100644 index 0000000000..c286133df5 --- /dev/null +++ b/docs/getopts.tex @@ -0,0 +1,135 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\chapter{The GETOPTS unit.} +This document describes the GETOPTS unit for Free Pascal. It was written for +\linux\ by Micha\"el Van Canneyt. It also works under DOS. + +The chapter is divided in 2 sections: +\begin{itemize} +\item The first section lists types, constants and variables from the +interface part of the unit. +\item The second section describes the functions defined in the unit. +\end{itemize} + +\section {Types, Constants and variables : } +\subsection{Constants} +\var{No\_Argument=0} : Specifies that a long option does not take an +argument. \\ +\var{Required\_Argument=1} : Specifies that a long option needs an +argument. \\ +\var{Optional\_Argument=2} : Specifies that a long option optionally takes an +argument. \\ +\var{EndOfOptions=\#255} : Returned by getopt, getlongopts to indicate that +there are no more options. +\subsection{Types} +\begin{verbatim} +Option = record + Name : string; + Has_arg : Integer; + Flag : ^Char; + Value : Char; + end; +POption = ^Option; +\end{verbatim} +The \var{option} type is used to communicate the long options to \var{GetLongOpts}. +The \var{Name} field is the name of the option. \var{Has\_arg} specifies if the option +wants an argument, \var{Flag} is a pointer to a \var{char}, which is set to +\var{Value}, if it is non-\var{nil}. + +\var{POption} is a pointer to a +\var{Option} record. It is used as an argument to the \var{GetLongOpts} +function. + +\subsection{Variables} +\var{OptArg:String} \ Is set to the argument of an option, if the option needs +one.\\ +\var{Optind:Integer} \ Is the index of the current \var{paramstr()}. When +all options have been processed, \var{optind} is the index of the first +non-option parameter. This is a read-only variable. Note that it can become +equal to \var{paramcount+1}\\ +\var{OptErr:Boolean} \ Indicates whether \var{getopt()} prints error +messages.\\ +\var{OptOpt:Char} \ In case of an error, contains the character causing the +error. +\section {Procedures and functions} +\function {Getopt}{(Shortopts : String)}{Char} +{ +Returns the next option found on the command-line. If no more options are +found, returns \var{EndOfOptions}. If the option requires an argument, it is +returned in the \var{OptArg} variable. + +\var{ShortOptions} is a string containing all possible one-letter options. +If a letter is followed by a colon (:), then that option needs an argument. +If a letter is followed by 2 colons, the option has an optional argument. + +If the first character of \var{shortoptions} is a \var{'+'} then options following a non-option are +regarded as non-options (standard Unix behavior). If it is a \var{'-'}, +then all non-options are treated as arguments of a option with character +\var{\#0}. This is useful for applications that require their options in +the exact order as they appear on the command-line. + +If the first character of \var{shortoptions} is none of the above, options +and non-options are permuted, so all non-options are behind all options. +This allows options and non-options to be in random order on the command +line. +} +{ +Errors are reported through giving back a \var{'?'} character. \var{OptOpt} +then gives the character which caused the error. If \var{OptErr} is +\var{True} then getopt prints an error-message to \var{stdout}. +} +{\seef{GetLongOpts}, \seem{getopt}{3}} + +\input{optex/optex.tex} + +\function {GetLongOpts}{(Shortopts : String, LongOpts : POption; var Longint +: Integer )}{Char} +{ +Returns the next option found on the command-line, taking into account long +options as well. If no more options are +found, returns \var{EndOfOptions}. If the option requires an argument, it is +returned in the \var{OptArg} variable. + +\var{ShortOptions} is a string containing all possible one-letter options. +(see \seef{Getopt} for its description and use) + +\var{LongOpts} is a pointer to the first element of an array of \var{Option} +records, the last of which needs a name of zero length. +The function tries to match the names even partially (i.e. \var{--app} +will match e.g. the \var{append} option), but will report an error in case of +ambiguity. + +If the option needs an argument, set \var{Has\_arg} to +\var{Required\_argument}, if the option optionally has an argument, set +\var{Has\_arg} to \var{Optional\_argument}. If the option needs no argument, +set \var{Has\_arg} to zero. + + +Required arguments can be specified in two ways : +\begin{enumerate} +\item \ Pasted to the option : \var{--option=value} +\item \ As a separate argument : \var {--option value} +\end{enumerate} +Optional arguments can only be specified through the first method. +} +{ see \seef{Getopt}, \seem{getopt}{3}} + +For an example, see \seef{Getopt} \ No newline at end of file diff --git a/docs/go32.tex b/docs/go32.tex new file mode 100644 index 0000000000..d372e71b81 --- /dev/null +++ b/docs/go32.tex @@ -0,0 +1,666 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\chapter{The GO32 unit.} +This chapter describes the \var{GO32} unit for Free Pascal under \dos. +The unit was first written for \dos by Florian kl\"ampfl. + +This chapter is divided in three sections. +\begin{itemize} +\item The first section is an introduction to the GO32 unit. +\item The second section lists the pre-defined constants, types and variables. +\item The third section describes the functions which appear in the +interface part of the GO32 unit. +\end{itemize} +Many function descriptions were made by Thomas Schatzl\footnote{ +E-Mail: \var{tom\_at\_work@geocities.com}}, for which my thanks. + +\section{Introduction} + +The GO32 provides an interface to the \dos extender, \dos memory access, +I/O ports and processor access. Some of this functions work with all modes +of the extender, other only with DPMI. + +\subsection{DOS memory access} + +The \dos memory access is done by the \var{dosmem} +functions and it's \textbf {strongly recommended } to use these functions. + +Example: +\begin{verbatim} +function shift_state : byte; + + begin + { $40:$17 contains the current contents of the shift, + alt and strg keys} + dosmemget($40,$17,shift_state,1); + end; +\end{verbatim} +\subsection{I/O port access} + +The I/O port access is done by the \var{inport} and \var{outport} functions. +It's not necessary to use these functions but it makes life easier. \fpk +\textbf {doesn't} support the \var{PORT} array, as under Turbo Pascal. + +\subsection{Processor access} +There are some functions to access the segment registers, which makes +your work easier. + +\subsection{Interrupt redirection} + +The \file{GO32} unit helps you to redirect interrupts. \var{SetIntVec} +and \var{GetIntVec} don't work with \fpk. This is now done via the functions +\var{set\_pm\_interrupt} and \var{get\_pm\_interrupt}. + +As an example we show how to redirect the interrupt \var{8h}. +\begin{verbatim} +{ the unit CRT _is_ needed because the program doesn't get + an interrupt while DOS is active } +uses + go32,crt; + +var + timer : longint; + ds : word; + +procedure s; { interrupt;} + { comes with versions > 0.9.2 of FPKPascal } + + begin + asm + { save used registers } + pushl %eax + pushw %ds + { load ds } + { prefix for cs } + .byte 0x2e + movw ALAB,%ax + movw %ax,%ds + end; + inc(timer); + asm + { restore processor state } + popw %ds + popl %eax + leave + { call old interrupt } + ljmp %cs:OLDINT + iret + { we need some data in the code segment, } + { since only CS is set in the } + { entry point of the procedure } + ALAB: + .word 0 + { old vector as 48 bit pointer (16:32) } + OLDINT: + .long 0 + .word 0 + end; + end; + + var + oldint,myint : tseginfo; + i : longint; + + begin + timer:=0; + { save old interrupt } + get_pm_interrupt(8,oldint); + ds:=get_ds; + asm + { copy some data to the code segment } + movw _DS,%ax + movw %ax,ALAB + movl _OLDINT,%eax + movl %eax,OLDINT + movw _OLDINT+4,%ax + movw %ax,OLDINT+4 + end; + { new handler } + myint.segment:=get_cs; + myint.offset:=@s; + { install the handler } + set_pm_interrupt(8,myint); + { do something } + for i:=1 to 10000 do + writeln(timer); + { install the old handler } + set_pm_interrupt(8,oldint); + end. +\end{verbatim} + +\section{Types, Variables and Constants} +\subsection{Constants} +\begin{verbatim} +Const +rm_unknown = 0; +rm_raw = 1; { raw (without HIMEM) } +rm_xms = 2; { XMS (for example with HIMEM, without EMM386) } +rm_vcpi = 3; { VCPI (for example HIMEM and EMM386) } +rm_dpmi = 4; { DPMI (for example DOS box or 386Max) } +\end{verbatim}\label{co:rmmode} +These constants can be returned by the \htmlref{get\_run\_mode}{GetRunMode} function. +\subsection{Types} +\begin{verbatim} +type + tmeminfo = record + available_memory : longint; + available_pages : longint; + available_lockable_pages : longint; + linear_space : longint; + unlocked_pages : longint; + available_physical_pages : longint; + total_physical_pages : longint; + free_linear_space : longint; + max_pages_in_paging_file : longint; + reserved : array[0..2] of longint; + end; +\end{verbatim}\label{ty:tmeminfo} +Returns information about the memory allocation etc. + +\textbf {NOTE:} The +value of a field is zero if the value is unknown, it's only guaranteed, +that \var{available\_memory} contains a valid value. +\begin{verbatim} +type +trealregs = record + case integer of + 1: { 32-bit } (EDI, ESI, EBP, Res, EBX, EDX, ECX, EAX: longint; + Flags, ES, DS, FS, GS, IP, CS, SP, SS: word); + 2: { 16-bit } (DI, DI2, SI, SI2, BP, BP2, R1, R2: word; + BX, BX2, DX, DX2, CX, CX2, AX, AX2: word); + 3: { 8-bit } (stuff: array[1..4] of longint; + BL, BH, BL2, BH2, DL, DH, DL2, DH2, + CL, CH, CL2, CH2, AL, AH, AL2, AH2: byte); + 4: { Compat } (RealEDI, RealESI, RealEBP, RealRES, + RealEBX, RealEDX, RealECX, RealEAX: longint; + RealFlags, + RealES, RealDS, RealFS, RealGS, + RealIP, RealCS, RealSP, RealSS: word); +end; + +registers = trealregs; +\end{verbatim}\label{ty:trealregs} +This data structure is used to pass register values to an real mode +interrupt handler. +\begin{verbatim} +type + tseginfo = record + offset : pointer; + segment : word; + end; +\end{verbatim}\label{ty:tseginfo} +This record is used to store a 48-bit pointer. +\subsection{Variables.} +\begin{verbatim} +var + { puts count bytes from data to ptr(seg:ofs) of the DOS memory } + dosmemput : procedure(seg : word;ofs : word;var data;count : longint); + + { gets count bytes from ptr(seg:ofs) of the DOS memory to data } + dosmemget : procedure(seg : word;ofs : word;var data;count : longint); + + { moves count bytes from ptr(sseg:sofs) to ptr(dseg:dofs) } + dosmemmove : procedure(sseg,sofs,dseg,dofs : word;count : longint); + + { fills count bytes beginning with ptr(seg:ofs) with c } + dosmemfillchar : procedure(seg,ofs : word;count : longint;c : char); + + { fills count words beginning with ptr(seg:ofs) with w } + { this function is especially used by the CRT unit. } + dosmemfillword : procedure(seg,ofs : word;count : longint;w : word); +\end{verbatim} +These procedure variables give you access to the \dos memory in each mode +of the \dos extender. It is strongly recommended to use these functions. + +The procedural variables are assigned by the startup code of the \var{GO32} +unit to the correct procedures. +\begin{verbatim} +var + dosmemselector : word; +\end{verbatim} +Selector to the \dos memory. The whole \dos memory is mapped to a +single segment. This function will only work in DPMI mode. + +\section{Functions and Procedures} +\procedure {Disable}{}{ +Clears the interrupt flag with CLD and disables the interrupts. +} +{None.}{\seep{Enable}} +\par {\bf NOTE: }This +function works only in DPMI mode\par + +\procedure{Enable}{}{ +Sets the interrupt flag with STI and allows the processor to handle +interrupts. +}{None.}{\seep{Disable}} + +\procedurel{get\_meminfo}{GetMeminfo}{(var meminfo : tmeminfo)}{ +Returns the current state of memory allocation of the \dos extender. + +\textbf{NOTE: }This procedure has nothing to do with the Pascal function +\var{maxavail} and \var{memavail}.}{None.} +{\htmlref{tmeminfo}{ty:tmeminfo}} + +\procedurel{get\_pm\_interrupt}{GetPmInterrupt}{(vector : byte;var intaddr : tseginfo)} +{ +Returns the address of the current protected mode handler for the interrupt +\var{vector}.}{None.} +{\seep{SetPmInterrupt},\htmlref{tseginfo}{ty:tseginfo}} + +\functionl{get\_run\_mode}{GetRunMode}{}{word}{ +This function returns the mode which the extender is currently running. +The function is mostly used to determine if DPMI is supported. + + +}{None.} +{\htmlref{rm}{co:rmmode}} +Example : +\begin{verbatim} +uses + go32; + +begin + if get_run_mode=rm_dpmi then + writeln('DPMI available') + else + writeln('No DPMI available'); +end. +\end{verbatim} + +\functionl{get\_cs}{GetCs}{}{word}{Returns the value of the CS +register.}{None.}{\seef{GetDs},\seef{GetSs}} + +\functionl{get\_ds}{GetDs}{}{word}{Returns the value of the DS +register.}{None.}{\seef{GetCs},\seef{GetSs}} + +\functionl{get\_ss}{GetSs}{word}{Returns the value of the SS +register.}{None.}{\seef{GetDs},\seef{GetCs}} + +\function{inportb}{(port : word)}{byte}{Reads a byte from the given I/O +port.}{None.}{\seep{outportb},\seef{inportw},\seef{inportl}} + +\function{inportw}{(port : word)}{word}{Reads a word from the given I/O +port.}{None.}{\seep{outportw},\seef{inportb},\seef{inportl}} + +\function{inportl}{(port : word)}{longint}{Reads a longint from the given I/O +port.}{None.}{\seep{outportl},\seef{inportw},\seef{inportb}} + +\procedure{outportb}{(port : word;data : byte)}{Writes a byte to the +specified port.}{None.}{\seef{inportb},\seep{outportw},\seep{outportl}} + +\procedure{outportw}{(port : word;data : word)}{Writes a word to the +specified port.}{None.}{\seef{inportw},\seep{outportb},\seep{outportl}} + +\procedure{outportl}{(port : word;data : longint)}{Writes a longint to the +specified port.}{None.}{\seef{inportl},\seep{outportb},\seep{outportw}} + +\procedure{realintr}{(intnr : word;var regs : trealregs)}{ +\textbf {NOTE: }This procedure works only in DPMI mode.} +{None.}{} + +\procedurel{seg\_fillchar}{SegFillChar}{(seg : word;ofs : longint;count : longint;c : +char)} +{Fills a memory area specified by a 48 bit pointer with the given number +of chars. + +\textbf {NOTE:} Be careful using this function in non-DPMI mode. +}{None.}{\seep{SegFillWord}, \seep{SegMove}} + +\procedurel {seg\_fillword}{SegFillWord}{(seg : word;ofs : longint;count : longint;w : +word)}{Fills a memory area specified by a 48 bit pointer with the given number +of words. + +\textbf {NOTE:} Be careful using this function in non-DPMI mode. +}{None.}{\seep{SegFillChar}, \seep{SegMove}} + +\procedurel{seg\_move}{SegMove}{(sseg : word;source : longint;dseg : word;dest : longint;count : +longint)} +{This procedure copies data when the source and destination are specified +by 48 bit pointers. For example, this function is used by the DPMI version +of \var{dosmemget} and \var{dosmemput}. }{The procedure checks only +for overlapping if source selector equals the destination selector. +Be also careful using this function in non-DPMI +mode.}{\seep{SegFillWord},\seep{SegFillChar}} + +\procedurel{set\_pm\_interrupt}{SetPmInterrupt}{(vector : byte;const intaddr : tseginfo)} +{Sets a new protected mode handler for the interrupt \var{vector}.} +{None.}{\seep{GetPmInterrupt}, \htmlref{tseginfo}{ty:tseginfo}} + +\functionl{Allocate\_Ldt\_Descriptors}{AllocateLdtDescriptors}{(Count : +word)}{word} +{\var{Allocate\_ldt\_descriptors} allocates \var{Count} descriptors in the +Local Descriptor Table (LDT). +The descriptors allocated must be initialized by the application with +other function calls. + +The function returns a base descriptor with a limit and size value set to +zero. + +{\em Notes:} +\begin{itemize} +\item Only works with real DPMI. +\item If more than one descriptor was requested, the function returns a base +selector referencing the first of a contiguous array of descriptors. The +selector values for subsequent descriptors in the array can be +calculated by adding the value returned by +\var{get\_next\_selector\_increment\_value.} +\end{itemize} +}{None.}{ +\seep{SetSegmentBaseAddress}, +\seep{SetSegmentLimit}, +\seef{GetLinearAddr}, +\seep{FreeLdtDescriptor}, +\seef{GetNextSelectorIncrementValue} +} +\begin{FPKList} +\item[Example] +\begin{verbatim} +uses go32; + +var VGAsel : word; + r : trealregs; + +begin + {...} + r.realeax := $13; realintr($10, r); + { set VGA mode } + {...} + VGAsel := allocate_ldt_descriptors(1); + { allocate one descriptor to the VGA } + set_segment_base_address(VGAsel, + get_linear_address($A0000, + $FFFF)); + { set the base address to the VGA } + set_segment_limit(VGAsel, $FFFF); + { set the limit of the descriptor } + {...} + seg_fillchar(VGAsel, 100*320+6, 1, 15); + { put a pixel at (6/100) in color 15 } + readln; + {...} + free_ldt_descriptor(sel); + r.realeax := $3; realintr($10, r); + { set textmode again } + {...} +end. +\end{verbatim} +\end{FPKList} + +\procedurel{Free\_Ldt\_Descriptor}{FreeLdtDescriptor}{(Sel : word)} +{ +\var{Free\_Ldt\_Descriptor} frees a previously allocated selector +with descriptor \var{Sel} + +{\em Notes:} +\begin{itemize} +\item Only works with real DPMI. +\item After this call this selector is invalid and must not be used for any +memory operations anymore. +\item Each descriptor allocated with \var{allocate\_ltd\_descriptor} must be +freed +individually with this function, even if it was previously allocated as +a part of a contiguous array of descriptors. +\end{itemize} +} +{None.} +{\seef{AllocateLdtDescriptors}} + +For an example, see \seef{AllocateLdtDescriptors}. + +\functionl{Segment\_To\_Descriptor}{SegmentToDescriptor}{(Seg : Word)}{Word} +{\var{Segment\_To\_Descriptor} Maps a real mode segment (paragraph) address +(in \var{Seg}) onto an descriptor that can be used by a protected mode +program to access the same memory. + +The function returns a selector to the DOS real-mode segment. + +{\em Notes:} +\begin{itemize} +\item Only works with real DPMI. +\item The descriptors limit will be set to 64KB. +\item multiple calls to this function with the same segment address will + return the same selector. +\item Descriptors created by this function can never be modified or freed. +For this reason this function shouldn't be used too often. Programs +which need to examine various real mode addresses using the same +selector should use the function \var{allocate\_ldt\_descriptors} and change +the base address as necessary. +\end{itemize} +} +{None.} +{} +\begin{FPKList} +\item[Example] +\begin{verbatim} +uses go32; + +var r : trealregs; + VGAsel : word; + +begin + r.realeax := $13; realintr($10, r); + { set VGA mode 13h } + VGASel := segment_to_descriptor($A000); + {...} + seg_fillchar(VGAsel, 100*320+6, 1, 15); + { put a pixel at (6/100) in color 15 } + readln; + {...} + r.realeax := $3; realintr($10, r); +end. +\end{verbatim} +\end{FPKList} + + +\Functionl{Get\_Next\_Selector\_Increment\_Value} +{GetNextSelectorIncrementValue}{word} +{\var{Get\_Next\_Selector\_Increment\_Value} returns the selector increment +value when allocating multiple subsequent descriptors + +The function \var{allocate\_ldt\_descriptors} can allocate an array of +contiguous descriptors, but only return the selector for the first. The +value returned by this function can be used to calculate the selectors +for subsequent descriptors in the array. + +{\em Notes:} +\begin{itemize} +\item Only works under real DPMI. +\item the increment is always a power of 2. +\end{itemize} +} +{None.} +{\seef{AllocateLdtDescriptors}} + +\functionl{Get\_Segment\_Base\_Address}{GetSegmentBaseAddress}{(Sel: word)}{Longint} +{ +\var{Get\_Segment\_Base\_Address} returns the 32-bit linear base address +from the LDT descriptor for the specified segment (\var{Sel}). + + +{\em Notes:} +\begin{itemize} +\item Only works under real DPMI. +\end{itemize} +} +{None.} +{\seep{SetSegmentBaseAddress}} + +\begin{FPKList} +\item[Example:] +\begin{verbatim} +uses go32; + +begin + Writeln(get_segment_base_address(get_ds)); +end. +\end{verbatim} +\end{FPKList} + +\procedurel{Set\_Segment\_Base\_Address}{SetSegmentBaseAddress} +{(var Des : word;Sel : longint)} +{\var{{Set\_Segment\_Base\_Address}} sets the 32-bit linear base address +of the descriptor \var{Des} for the specified selector \var{Sel}. + +{\em Notes:} +\begin{itemize} +\item only works under real DPMI +\end{itemize} +} +{None.} +{ \seef{AllocateLdtDescriptors}, \seep{SetSegmentLimit}} + +For an example, see \seef{AllocateLdtDescriptors}. + +\procedurel{Set\_Segment\_Limit}{SetSegmentLimit}{(Des : word;Len : longint)} +{\var{Set\_Segment\_Limit} sets the limit of the descriptor \var{Des} +to the specified length \var{Len} + +{\em Notes:} +\begin{itemize} +\item Only works under real DPMI. +\item The new limit is the byte length of the segment-1. +\item Segment limits bigger than or equal to 1MB must be page aligned, they +must have the lower 12 bits set. +\end{itemize} +} +{None} +{ \seep{SetSegmentBaseAddress}, \seef{AllocateLdtDescriptors}} + +For an example, see \seef{AllocateLdtDescriptors}. + +\functionl{Create\_Code\_Segment\_Alias\_Descriptor} +{CreateCodeSegmentAliasDescriptor}{(Des : Word)}{Word} +{\var{Create\_Code\_Segment\_Alias\_Descriptor} +Creates a new descriptor that has the same base and limit as the +specified descriptor. In effect, the function returns a copy of the +descriptor. + +{\em Notes:} +\begin{itemize} +\item Only works under real DPMI. +\item The descriptor alias returned by this function will not track changes +to the original descriptor. In other words, if an alias is created with +this function, and the base or limit of the original segment is then +changed, the two descriptors will no longer map the same memory. +\end{itemize} +} +{None.} +{} +\begin{FPKList} +\item[Example] +\begin{verbatim} +uses go32; + +var copysel : word; + +begin + copysel := create_code_segment_alias_descriptor(get_ds); + {...} + free_ldt_descriptor(copysel); +end. +\end{verbatim} +\end{FPKList} + +\functionl{Get\_Linear\_Addr}{GetLinearAddr}{(PhysAddr : longint;Size : longint)}{longint} +{\var{Get\_Linear\_Addr} converts a physical address \var{PhysAddr} into +a linear address. + +{\em Notes:} +\begin{itemize} +\item Only works under real DPMI. +\end{itemize} +}{None.}{} + +For an example, see \seef{AllocateLdtDescriptors}. + +\functionl{Global\_Dos\_Alloc}{GlobalDosAlloc}{(Len : longint)}{longint} +{\var{Global\_Dos\_Alloc} +allocates a block of memory with length \var{Len} from the \dos memory pool, +i.e. memory below the 1 MB boundary that is controlled by \dos. +Such memory blocks are typically used to exchange data with real mode +programs, TSRs, or device drivers. + +The function returns both the real mode segment base address of +the block and one or more descriptors that can be used by protected mode +applications to access the block. +The high word is the selector to this block, and the low word the +\dos real mode segment. The offset of this block is always zero. + +{\em Notes:} +\begin{itemize} +\item Should only used for temporary buffers to get real mode information +(e.g. interrupts that need a data structure in ES:DI), because every +single block needs an unique selector. +\end{itemize} +}{None.}{\seep{GlobalDosFree}} + +\begin{FPKList} +\item[Example] +\begin{verbatim} +uses go32; + +procedure dosalloc (var selector : word; + var segment : word; + size : longint); +var result : longint; + +begin + result := global_dos_alloc(size); + selector := word(result); + segment := word(result shr 16); +end; + +procedure dosfree(selector : word); +begin + global_dos_free(selector); +end; + +var selector : word; + segment : word; + r : trealregs; + +begin + fillchar(r, sizeof(r), 0); + fillchar(any_record, sizeof(any_record), 0); + dosalloc(selector, segment, sizeof(VBE_vgainfo)); + { allocate a real mode memory block } + any_record.any_entry := 1000; + dosmemput(segment, 0, any_record, sizeof(any_record)); + { copy the record to real mode memory } + r.realeax := $0000; + r.reales := segment; r.realedi := 0; + realintr(IntNr, r); { do our interrupt } + dosmemget(segment, 0, any_record, sizeof(any_record)); + { get the record from real mode memory } + dosfree(selector); { free selector afterwards } +end. +\end{verbatim} +\end{FPKList} + +\procedurel{Global\_Dos\_Free}{GlobalDosFree}{(Sel : word)} +{var{Global\_Dos\_Free} frees a previously allocated \dos memory +block, described by selector \var{Sel}. +} +{None.} +{\seef{GlobalDosAlloc}} + +For an example, see \seef{GlobalDosAlloc}. + diff --git a/docs/graph.tex b/docs/graph.tex new file mode 100644 index 0000000000..01317b21f9 --- /dev/null +++ b/docs/graph.tex @@ -0,0 +1,554 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +% Documentation for the 'Graph' unit of Free Pascal. +% Michael Van Canneyt, July 1997 +\chapter{The GRAPH unit.} +This document describes the \var{GRAPH} unit for Free Pascal, under \dos. +The unit was first written for \dos by Florian kl\"ampfl. + +This chapter is divided in three sections. +\begin{itemize} +\item The first section gives an introduction to the graph unit. +\item The second section lists the pre-defined constants, types and variables. +\item The second section describes the functions which appear in the +interface part of the \file{GRAPH} unit. +\end{itemize} + +\section{Introduction} +\label{se:Introduction} +\subsection{Requirements} +The unit Graph exports functions and procedures for graphical output. +It requires at least a VESA compatible VGA-Card or a VGA-Card with software-driver +(min. \textbf{512Kb} video memory). + +Before the graph unit can be used, be sure your graphics adapter supports +the VESA-Standard. Otherwise in the most cases you can try to use a VESA-TSR +to make your adapter VESA compatible (e.g. UNIVBE). + +\section{Constants, Types and Variables} +\subsection{Types} +\begin{verbatim} +ArcCoordsType = record + X,Y,Xstart,Ystart,Xend,Yend : Integer; +end; + +FillPatternType = Array [1..8] of Byte; + +FillSettingsType = Record + Pattern,Color : Word +end; + +LineSettingsType = Record + LineStyle,Pattern, Width : Word; +end; + +PaletteType = Record + Size : Byte; + Colors : array[0..MAxColor] of shortint; +end; + +PointType = Record + X,Y : Integer; +end; + +TextSettingsType = Record + Font,Direction, CharSize, Horiz, Vert : Word +end; + +ViewPortType = Record + X1,Y1,X2,Y2 : Integer; + Clip : Boolean +end; +\end{verbatim} + +\section{Functions and procedures} +\procedure{Arc}{(X,Y : Integer; start,stop, radius : Word)} +{ \var{Arc} draws part of a circle with center at \var{(X,Y)}, radius +\var{radius}, starting from angle \var{start}, stopping at angle \var{stop}. +These angles are measured +counterclockwise.}{None.}{\seep{Circle},\seep{Ellipse} +\seep{GetArcCoords},\seep{PieSlice}, \seep{Sector}} + +\procedure{Bar}{(X1,Y1,X2,Y2 : Integer)} +{Draws a rectangle with corners at \var{(X1,Y1)} and \var{(X2,Y2)} +and fills it with the current color and fill-style.}{None.}{\seep{Bar3D}, +\seep{Rectangle}} + +\procedure{Bar3D}{(X1,Y1,X2,Y2 : Integer; depth : Word; Top : Boolean)} +{Draws a 3-dimensional Bar with corners at \var{(X1,Y1)} and \var{(X2,Y2)} +and fills it with the current color and fill-style. +\var{Depth} specifies the number of pixels used to show the depth of the +bar. + +If \var{Top} is true; then a 3-dimensional top is drawn.} +{None.}{\seep{Bar}, \seep{Rectangle}} + +\procedure{Circle}{(X,Y : Integer; Radius : Word)} +{ \var{Circle} draws part of a circle with center at \var{(X,Y)}, radius +\var{radius}.}{None.}{\seep{Ellipse},\seep{Arc} +\seep{GetArcCoords},\seep{PieSlice}, \seep{Sector}} + +\procedure{ClearDevice}{}{Clears the graphical screen (with the current +background color), and sets the pointer at \var{(0,0)}}{None.} +{\seep{ClearViewPort}, \seep{SetBkColor}} + +\procedure{ClearViewPort}{} +{Clears the current view-port. The current background color is used as filling +color. The pointer is set at +\var{(0,0)}}{None.}{\seep{ClearDevice},\seep{SetViewPort}, \seep{SetBkColor}} + +\procedure{CloseGraph}{}{Closes the graphical system, and restores the +screen modus which was active before the graphical modus was +activated.}{None.}{\seep{InitGraph}} + +\procedure{DetectGraph}{(Var Driver, Modus : Integer)} +{ Checks the hardware in the PC and determines the driver and screen-modus to +be used. These are returned in \var{Driver} and \var{Modus}, and can be fed +to \var{InitGraph}. + +See the \var{InitGraph} for a list of drivers and modi.} +{None.}{\seep{InitGraph}} + +\procedure{DrawPoly}{(NumberOfPoints : Word; Var PolyPoints}{ +Draws a polygone with \var{NumberOfPoints} corner points, using the +current color and line-style. PolyPoints is an array of type \var{PointType}. +}{None.}{\seep{Bar}, seep{Bar3D}, \seep{Rectangle}} + +\procedure{Ellipse}{(X,Y : Integer; Start,Stop,XRadius,YRadius : Word)} +{ \var{Ellipse} draws part of an ellipse with center at \var{(X,Y)}. +\var{XRadius} and \var{Yradius} are the horizontal and vertical radii of the +ellipse. \var{Start} and \var{Stop} are the starting and stopping angles of +the part of the ellipse. + +They are measured counterclockwise from the X-axis.} +{None.}{\seep{Arc} \seep{Circle}, \seep{FillEllipse}} + +\procedure{FillEllipse}{(X,Y : Integer; Xradius,YRadius: Word)} +{ \var{Ellipse} draws an ellipse with center at \var{(X,Y)}. +\var{XRadius} and \var{Yradius} are the horizontal and vertical radii of the +ellipse. The ellipse is filled with the current color and fill-style.} +{None.}{\seep{Arc} \seep{Circle}, +\seep{GetArcCoords},\seep{PieSlice}, \seep{Sector}} + +\procedure{FillPoly}{(NumberOfPoints : Word; Var PolyPoints)}{ +Draws a polygone with \var{NumberOfPoints} corner points and fills it +using the current color and line-style. + +PolyPoints is an array of type \var{PointType}. +}{None.}{\seep{Bar}, seep{Bar3D}, \seep{Rectangle}} + +\procedure{FloodFill}{(X,Y : Integer; BorderColor : Word)}{ +Fills the area containing the point \var{(X,Y)}, bounded by the color +\var{BorderColor}.}{None}{\seep{SetColor}, \seep{SetBkColor}} + +\procedure{GetArcCoords}{(Var ArcCoords : ArcCoordsType)} +{\var{GetArcCoords} returns the coordinates of the latest \var{Arc} or +\var{Ellipse} call.} +{None.}{\seep{Arc}, \seep{Ellipse}} + +\procedure{GetAspectRatio}{(Var Xasp,Yasp : Word)} +{\var{GetAspectRatio} determines the effective resolution of the screen. The aspect ration can +the be calculated as \var{Xasp/Yasp}.}{None.}{\seep{InitGraph},\seep{SetAspectRatio}} + +\Function{GetBkColor}{Word}{\var{GetBkColor} returns the current background color (the palette +entry).}{None.}{\seef{GetColor},\seep{SetBkColor}} + +\Function{GetColor}{Word}{\var{GetColor} returns the current drawing color (the palette +entry).}{None.}{\seef{GetColor},\seep{SetBkColor}} + +\procedure {GetDefaultPalette}{(Var Palette : PaletteType)}{Returns the +current palette in \var{Palette}.}{None.}{\seef{GetColor}, \seef{GetBkColor}} + +\Function{GetDriverName}{String}{\var{GetDriverName} returns a string containing the name of the +current driver.}{None.}{\seef{GetModeName}, \seep{InitGraph}} + +\procedure{GetFillPattern}{(Var FillPattern : FillPatternType)} +{\var{GetFillPattern} returns an array with the current fill-pattern in \var{FillPattern}} +{None}{\seep{SetFillPattern}} + +\procedure{GetFillSettings}{(Var FillInfo : FillSettingsType)} +{\var{GetFillSettings} returns the current fill-settings in +\var{FillInfo}}{None.}{\seep{SetFillPattern}} + +\Function{GetGraphMode}{Integer}{\var{GetGraphMode} returns the current graphical modus} +{None.}{\seep{InitGraph}} + +\procedure{GetImage}{(X1,Y1,X2,Y2 : Integer, Var Bitmap}{\var{GetImage} +Places a copy of the screen area \var{(X1,Y1)} to \var{X2,Y2} in \var{BitMap}} +{Bitmap must have enough room to contain the image.}{\seef{ImageSize}, +\seep{PutImage}} + +\procedure{GetLineSettings}{(Var LineInfo : LineSettingsType)} +{\var{GetLineSettings} returns the current Line settings in +\var{LineInfo}}{None.}{\seep{SetLineStyle}} + +\Function{GetMaxColor}{Word}{\var{GetMaxColor} returns the maximum +color-number which can be set with \var{SetColor}}{None.}{\seep{SetColor}, +\seef{GetPaletteSize}} + +\Function{GetMaxMode}{Word}{\var{GetMaxMode} returns the highest modus for +the current driver.}{None.}{\seep{InitGraph}} + +\Function{GetMaxX}{Word}{\var{GetMaxX} returns the maximum horizontal screen +length}{None.}{\seef{GetMaxY}} + +\Function{GetMaxY}{Word}{\var{GetMaxY} returns the maximum number of screen +lines}{None.}{\seef{GetMaxY}} + +\function{GetModeName}{(Var modus : Integer)}{String}{ +Returns a string with the name of modus +\var{Modus}}{None.}{\seef{GetDriverName}, \seep{InitGraph}} + +\procedure{GetModeRange}{(Driver : Integer; \\ LoModus, HiModus: Integer)} +{\var{GetModeRange} returns the Lowest and Highest modus of the currently +installed driver.}{None.}{\seep{InitGraph}} + +\procedure{GetPalette}{(Var Palette : PaletteType)} +{\var{GetPalette} returns in \var{Palette} the current palette.} +{None.}{\seef{GetPaletteSize}, \seep{SetPalette}} + +\Function{GetPaletteSize}{Word}{\var{GetPaletteSize} returns the maximum +number of entries in the current palette.}{None.}{\seep{GetPalette}, +\seep{SetPalette}} + +\function{GetPixel}{(X,Y : Integer)}{Word}{\var{GetPixel} returns the color +of the point at \var{(X,Y)} }{None.}{} + +\procedure{GetTextSettings}{(Var TextInfo : TextSettingsType)} +{\var{GetTextSettings} returns the current text style settings : The font, +direction, size and placement as set with \var{SetTextStyle} and +\var{SetTextJustify}}{None.}{\seep{SetTextStyle}, \seep{SetTextJustify}} + +\procedure{GetViewSettings}{(Var ViewPort : ViewPortType)} +{\var{GetViewSettings} returns the current view-port and clipping settings in +\var{ViewPort}.}{None.}{\seep{SetViewPort}} + +\Function{GetX}{Integer}{\var{GetX} returns the X-coordinate of the current position of +the graphical pointer}{None.}{\seef{GetY}} + +\Function{GetY}{Integer}{\var{GetY} returns the Y-coordinate of the current position of +the graphical pointer}{None.}{\seef{GetX}} + +\Procedure{GraphDefaults}{\var{GraphDefaults} resets all settings for view-port, palette, +foreground and background pattern, line-style and pattern, filling style, +filling color and pattern, font, text-placement and +text size.}{None.}{\seep{SetViewPort}, \seep{SetFillStyle}, \seep{SetColor}, +\seep{SetBkColor}, \seep{SetLineStyle}} + +\function{GraphErrorMsg}{(ErrorCode : Integer)}{String}{\var{GraphErrorMsg} +returns a string describing the error \var{Errorcode}. This string can be +used to let the user know what went wrong.}{None.}{\seef{GraphResult}} + +\Function{GraphResult}{Integer}{\var{GraphResult} returns an error-code for +the last graphical operation. If the returned value is zero, all went well. +A value different from zero means an error has occurred. +Except for all operations which draw something on the screen, +the following procedures also can produce a \var{GraphResult} different from +zero: +\begin{itemize} +\item \seef{InstallUserFont} +\item \seep{SetLineStyle} +\item \seep{SetWriteMode} +\item \seep{SetFillStyle} +\item \seep{SetTextJustify} +\item \seep{SetGraphMode} +\item \seep{SetTextStyle} +\end{itemize} +}{None.}{\seef{GraphErrorMsg}} + +\function{ImageSize}{(X1,Y1,X2,Y2 : Integer)}{Word}{\var{ImageSize} returns +the number of bytes needed to store the image in the rectangle defined by +\var{(X1,Y1)} and \var{(X2,Y2)}.}{None.}{\seep{GetImage}} + +\procedure{InitGraph}{(var GraphDriver,GraphModus : integer;\\ +const PathToDriver : string)}{ +\var{InitGraph} initializes the \var{graph} package. + +\var{GraphDriver} has two valid values: \var{GraphDriver=0} which +performs an auto detect and initializes the highest possible mode with the most +colors. 1024x768x64K is the highest possible resolution supported by the +driver, if you need a higher resolution, you must edit \file{MODES.PPI}. +If you need another mode, then set \var{GraphDriver} to a value different +from zero +and \var{graphmode} to the mode you wish (VESA modes where 640x480x256 +is \var {101h} etc.). + +\var{PathToDriver} is only needed, if you use the BGI fonts from +Borland.}{None.}{Introduction, (page \pageref{se:Introduction}), +\seep{DetectGraph}, \seep{CloseGraph}, \seef{GraphResult}} + +Example: + +\begin{verbatim} +var + gd,gm : integer; + PathToDriver : string; + +begin + gd:=detect; { highest possible resolution } + gm:=0; { not needed, auto detection } + PathToDriver:='C:\PP\BGI'; { path to BGI fonts, + drivers aren't needed } + InitGraph(gd,gm,PathToDriver); + if GraphResult<>grok then + halt; ..... { whatever you need } + CloseGraph; { restores the old graphics mode } +end. +\end{verbatim} + +\function{InstallUserDriver}{(DriverPath : String; \\AutoDetectPtr: Pointer)} +{Integer}{\var{InstallUserDriver} +adds the device-driver \var{DriverPath} to the list of .BGI +drivers. \var{AutoDetectPtr} is a pointer to a possible auto-detect function.} +{None.}{\seep{InitGraph}, \seef{InstallUserFont}} + +\function{InstallUserFont}{(FontPath : String)}{Integer} +{\var{InstallUserFont} adds the font in \var{FontPath} to the list of fonts +of the .BGI system.} +{None.}{\seep{InitGraph}, \seef{InstallUserDriver}} + +\procedure{Line}{(X1,Y1,X2,Y2 : Integer)}{\var{Line} draws a line starting from +\var{(X1,Y1} to \var{(X2,Y2)}, in the current line style and color. The +current position is put to \var{(X2,Y2)}}{None.} +{\seep{LineRel},\seep{LineTo}} + +\procedure{LineRel}{(DX,DY : Integer)}{\var{LineRel} draws a line starting from +the current pointer position to the point\var{(DX,DY}, \textbf{relative} to the +current position, in the current line style and color. The Current Position +is set to the endpoint of the line.}{None.} +{\seep{Line}, \seep{LineTo}} + +\procedure{LineTo}{(DX,DY : Integer)}{\var{LineTo} draws a line starting from +the current pointer position to the point\var{(DX,DY}, \textbf{relative} to the +current position, in the current line style and color. The Current position +is set to the end of the line.}{None.} +{\seep{LineRel},\seep{Line}} + +\procedure{MoveRel}{(DX,DY : Integer}{\var{MoveRel} moves the pointer to the +point \var{(DX,DY)}, relative to the current pointer +position}{None.}{\seep{MoveTo}} + +\procedure{MoveTo}{(X,Y : Integer}{\var{MoveTo} moves the pointer to the +point \var{(X,Y)}.}{None.}{\seep{MoveRel}} + +\procedure{OutText}{(Const TextString : String)} +{\var{OutText} puts \var{TextString} on the screen, at the current pointer +position, using the current font and text settings. The current position is +moved to the end of the text.} +{None.}{\seep{OutTextXY}} + +\procedure{OutTextXY}{(X,Y : Integer; Const TextString : String)} +{\var{OutText} puts \var{TextString} on the screen, at position \var{(X,Y)}, +using the current font and text settings. The current position is +moved to the end of the text.} +{None.}{\seep{OutText}} + +\procedure{PieSlice}{(X,Y : Integer; \\ Start,Stop,Radius : Word)}{\var{PieSlice} +draws and fills a sector of a circle with center \var{(X,Y)} and radius +\var{Radius}, starting at angle \var{Start} and ending at angle \var{Stop}.} +{None.}{\seep{Arc}, \seep{Circle}, \seep{Sector}} + +\procedure{PutImage}{(X1,Y1 : Integer; Var Bitmap; How : word) }{\var{PutImage} +Places the bitmap in \var{Bitmap} on the screen at \var{(X1,Y1)}. \var{How} +determines how the bitmap will be placed on the screen. Possible values are : +\begin{itemize} +\item CopyPut +\item XORPut +\item ORPut +\item AndPut +\item NotPut +\end{itemize}} +{None}{\seef{ImageSize},\seep{GetImage}} + +\procedure{PutPixel}{(X,Y : Integer; Color : Word)}{Puts a point at +\var{(X,Y)} using color \var{Color}}{None.}{\seef{GetPixel}} + +\procedure{Rectangle}{(X1,Y1,X2,Y2 : Integer)}{Draws a rectangle with +corners at \var{(X1,Y1)} and \var{(X2,Y2)}, using the current color and +style.}{None.}{\seep{Bar}, \seep{Bar3D}} + +\function{RegisterBGIDriver}{(Driver : Pointer)}{Integer} +{Registers a user-defined BGI driver}{None.}{\seef{InstallUserDriver}, +\seef{RegisterBGIFont}} + +\function{RegisterBGIFont}{(Font : Pointer)}{Integer} +{Registers a user-defined BGI driver}{None.}{\seef{InstallUserFont}, +\seef{RegisterBGIDriver}} + +\Procedure{RestoreCRTMode}{Restores the screen modus which was active before +the graphical modus was started.}{None.}{\seep{InitGraph}} + +\procedure{Sector}{(X,Y : Integer; \\ Start,Stop,XRadius,YRadius : Word)}{\var{Sector} +draws and fills a sector of an ellipse with center \var{(X,Y)} and radii +\var{XRadius} and \var{YRadius}, starting at angle \var{Start} and ending at angle \var{Stop}.} +{None.}{\seep{Arc}, \seep{Circle}, \seep{PieSlice}} + +\procedure{SetActivePage}{(Page : Word)}{Sets \var{Page} as the active page +for all graphical output.}{None.}{} + +\procedure{SetAllPallette}{(Var Palette)}{Sets the current palette to +\var{Palette}. \var{Palette} is an untyped variable, usually pointing to a +record of type \var{PaletteType}}{None.}{\seep{GetPalette}} + +\procedure{SetAspectRatio}{(Xasp,Yasp : Word)}{Sets the aspect ratio of the +current screen to \var{Xasp/Yasp}.} +{None}{\seep{InitGraph}, \seep{GetAspectRatio}} + +\procedure{SetBkColor}{(Color : Word)}{Sets the background color to +\var{Color}.}{None.}{\seef{GetBkColor}, \seep{SetColor}} + +\procedure{SetColor}{(Color : Word)}{Sets the foreground color to +\var{Color}.}{None.}{\seef{GetColor}, \seep{SetBkColor}} + +\procedure{SetFillPattern}{(FillPattern : FillPatternType,\\ Color : Word)} +{\var{SetFillPattern} sets the current fill-pattern to \var{FillPattern}, and +the filling color to \var{Color} + +The pattern is an 8x8 raster, corresponding to the 64 bits in +\var{FillPattern}.}{None}{\seep{GetFillPattern}, \seep{SetFillStyle}} + +\procedure{SetFillStyle}{(Pattern,Color : word)} +{\var{SetFillStyle} sets the filling pattern and color to one of the +predefined filling patterns. \var{Pattern} can be one of the following predefined +constants : +\begin{itemize} +\item \var{EmptyFill } Uses backgroundcolor. +\item \var{SolidFill } Uses filling color +\item \var{LineFill } Fills with horizontal lines. +\item \var{ltSlashFill} Fills with lines from left-under to top-right. +\item \var{SlashFill } Idem as previous, thick lines. +\item \var{BkSlashFill} Fills with thick lines from left-Top to bottom-right. +\item \var{LtBkSlashFill} Idem as previous, normal lines. +\item \var{HatchFill} Fills with a hatch-like pattern. +\item \var{XHatchFill} Fills with a hatch pattern, rotated 45 degrees. +\item \var{InterLeaveFill} +\item \var{WideDotFill} Fills with dots, wide spacing. +\item \var{CloseDotFill} Fills with dots, narrow spacing. +\item \var{UserFill} Fills with a user-defined pattern. +\end{itemize} +}{None.}{\seep{SetFillPattern}} + +\procedure{SetGraphBufSize}{(BufSize : Word)}{\var{SetGraphBufSize} +sets the graphical buffer size. The default size is 4Kb}{None.}{} + +\procedure{SetGraphMode}{(Mode : Integer)}{\var{SetGraphMode} sets the +graphical mode and clears the screen.}{None.}{\seep{InitGraph}} + +\procedure{SetLineStyle}{(LineStyle,Pattern,Width : +Word)}{\var{SetLineStyle} +sets the drawing style for lines. You can specify a \var{LineStyle} which is +one of the following pre-defined constants: +\begin{itemize} +\item \var{Solidln=0;} draws a solid line. +\item \var{Dottedln=1;} Draws a dotted line. +\item \var{Centerln=2;} draws a non-broken centered line. +\item \var{Dashedln=3;} draws a dashed line. +\item \var{UserBitln=4;} Draws a User-defined bit pattern. +\end{itemize} +If \var{UserBitln} is specified then \var{Pattern} contains the bit pattern. +In all another cases, \var{Pattern} is ignored. The parameter \var{Width} +indicates how thick the line should be. You can specify one of the following +pre-defined constants: +\begin{itemize} +\item \var{NormWidth=1} +\item \var{ThickWidth=3} +\end{itemize} +}{None.}{\seep{GetLineSettings}} + +\procedure{SetPalette}{(ColorNr : Word; NewColor : ShortInt)} +{\var{SetPalette} changes the \var{ColorNr}-th entry in the palette to +\var{NewColor}}{None.}{\seep{SetAllPallette},\seep{SetRGBPalette}} + +\procedure{SetRGBPalette}{(ColorNr,Red,Green,Blue : Integer)} +{\var{SetRGBPalette} sets the \var{ColorNr}-th entry in the palette to the +color with RGB-values \var{Red, Green Blue}.}{None.}{\seep{SetAllPallette}, +\seep{SetPalette}} + +\procedure{SetTextJustify}{(Horizontal,Vertical : Word)} +{\var{SetTextJustify} controls the placement of new text, relative to the +(graphical) cursor position. \var{Horizontal} controls horizontal placement, and can be +one of the following pre-defined constants: +\begin{itemize} +\item \var{LeftText=0;} Text is set left of the pointer. +\item \var{CenterText=1;} Text is set centered horizontally on the pointer. +\item \var{RightText=2;} Text is set to the right of the pointer. +\end{itemize} +\var{Vertical} controls the vertical placement of the text, relative to the +(graphical) cursor position. Its value can be one of the following +pre-defined constants : +\begin{itemize} +\item \var{BottomText=0;} Text is placed under the pointer. +\item \var{CenterText=1;} Text is placed centered vertically on the pointer. +\item \var{TopText=2;}Text is placed above the pointer. +\end{itemize} +}{None.}{\seep{OutText}, \seep{OutTextXY}} + +\procedure{SetTextStyle}{(Font,Direction,Magnitude : Word)} +{\var{SetTextStyle} controls the style of text to be put on the screen. +pre-defined constants for \var{Font} are: +\begin{itemize} +\item \var{DefaultFont=0;} +\item \var{TriplexFont=2;} +\item \var{SmallFont=2;} +\item \var{SansSerifFont=3;} +\item \var{GothicFont=4;} +\end{itemize} +Pre-defined constants for \var{Direction} are : +\begin{itemize} +\item \var{HorizDir=0;} +\item \var{VertDir=1;} +\end{itemize}}{None.}{\seep{GetTextSettings}} + +\procedure{SetUserCharSize}{(Xasp1,Xasp2,Yasp1,Yasp2 : Word)} +{Sets the width and height of vector-fonts. The horizontal size is given +by \var{Xasp1/Xasp2}, and the vertical size by \var{Yasp1/Yasp2}.}{None.} +{\seep{SetTextStyle}} + +\procedure{SetViewPort}{(X1,Y1,X2,Y2 : Integer; Clip : Boolean)} +{Sets the current graphical view-port (window) to the rectangle defined by +the top-left corner \var{(X1,Y1)} and the bottom-right corner \var{(X2,Y2)}. +If \var{Clip} is true, anything drawn outside the view-port (window) will be +clipped (i.e. not drawn). Coordinates specified after this call are relative +to the top-left corner of the view-port.}{None.}{\seep{GetViewSettings}} + +\procedure{SetVisualPage}{(Page : Word)} +{\var{SetVisualPage} sets the video page to page number \var{Page}. } +{None}{\seep{SetActivePage}} + +\procedure{SetWriteMode}{(Mode : Integer)} +{\var{SetWriteMode} controls the drawing of lines on the screen. It controls +the binary operation used when drawing lines on the screen. \var{Mode} can +be one of the following pre-defined constants: +\begin{itemize} +\item CopyPut=0; +\item XORPut=1; +\end{itemize}}{None.}{} + +\function{TextHeight}{(S : String)}{Word} +{\var{TextHeight} returns the height (in pixels) of the string \var{S} in +the current font and text-size. +}{None.}{\seef{TextWidth}} + +\function{TextWidth}{(S : String)}{Word} +{\var{TextHeight} returns the width (in pixels) of the string \var{S} in +the current font and text-size. +}{None.}{\seef{TextHeight}} + diff --git a/docs/html.sty b/docs/html.sty new file mode 100644 index 0000000000..191bb19f4c --- /dev/null +++ b/docs/html.sty @@ -0,0 +1,360 @@ +% LaTeX2HTML Version 95.1 : html.sty +% +% WARNING: This file requires LaTeX2e. A LaTeX 2.09 version +% is also provided, but with restricted functionality. +% +% This file contains definitions of LaTeX commands which are +% processed in a special way by the translator. +% For example, there are commands for embedding external hypertext links, +% for cross-references between documents or for including +% raw HTML. +% This file includes the comments.sty file v2.0 by Victor Eijkhout +% In most cases these commands do nothing when processed by LaTeX. + +% Modifications: +% +% nd = Nikos Drakos +% jz = Jelle van Zeijl +% hs = Herb Swan + +% hs 31-JAN-96 - Added support for document segmentation +% hs 10-OCT-95 - Added \htmlrule command +% jz 22-APR-94 - Added support for htmlref +% nd - Created +%%%%MG added +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{html} + [1996/02/01 v1.0 hypertext commands for latex2html (nd, hs)] +%%%%MG +% Exit if the style file is already loaded +% (suggested by Lee Shombert +\ifx \htmlstyloaded\relax \endinput\else\let\htmlstyloaded\relax\fi + +%%% LINKS TO EXTERNAL DOCUMENTS +% +% This can be used to provide links to arbitrary documents. +% The first argumment should be the text that is going to be +% highlighted and the second argument a URL. +% The hyperlink will appear as a hyperlink in the HTML +% document and as a footnote in the dvi or ps files. +% +\newcommand{\htmladdnormallinkfoot}[2]{#1\footnote{#2}} + +% This is an alternative definition of the command above which +% will ignore the URL in the dvi or ps files. +\newcommand{\htmladdnormallink}[2]{#1} + +% This command takes as argument a URL pointing to an image. +% The image will be embedded in the HTML document but will +% be ignored in the dvi and ps files. +% +\newcommand{\htmladdimg}[1]{} + +%%% CROSS-REFERENCES BETWEEN (LOCAL OR REMOTE) DOCUMENTS +% +% This can be used to refer to symbolic labels in other Latex +% documents that have already been processed by the translator. +% The arguments should be: +% #1 : the URL to the directory containing the external document +% #2 : the path to the labels.pl file of the external document. +% If the external document lives on a remote machine then labels.pl +% must be copied on the local machine. +% +%e.g. \externallabels{http://cbl.leeds.ac.uk/nikos/WWW/doc/tex2html/latex2html} +% {/usr/cblelca/nikos/tmp/labels.pl} +% The arguments are ignored in the dvi and ps files. +% +\newcommand{\externallabels}[2]{} + +% +% This complements the \externallabels command above. The argument +% should be a label defined in another latex document and will be +% ignored in the dvi and ps files. +% +\newcommand{\externalref}[1]{} + +% This command adds a horizontal rule and is valid even within +% a figure caption. +% +\newcommand{\htmlrule}{} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% The following commands pertain to document segmentation, and +% were added by Herbert Swan (with help from +% Michel Goossens ): +% +% +% This command inputs internal latex2html tables so that large +% documents can to partitioned into smaller (more manageable) +% segments. +% +\newcommand{\internal}[2][internals]{} + +% +% Define a dummy stub \htmlhead{}. This command causes latex2html +% to define the title of the start of a new segment. It is not +% normally placed in the user's document. Rather, it is passed to +% latex2html via a .ptr file written by \segment. +% +\newcommand{\htmlhead}[2]{} + +% +% The dummy command \endpreamble is needed by latex2html to +% mark the end of the preamble in document segments that do +% not contain a \begin{document} +% +\newcommand{\startdocument}{} + +% +% Allocate a new set of section counters, which will get incremented +% for "*" forms of sectioning commands, and for a few miscellaneous +% commands. +% + +\newcounter{lpart} +\newcounter{lchapter}[part] +\ifx\chapter\undefined\newcounter{lsection}[part]\else\newcounter{lsection}[chapter]\fi +\newcounter{lsubsection}[section] +\newcounter{lsubsubsection}[subsection] +\newcounter{lparagraph}[subsubsection] +\newcounter{lsubparagraph}[paragraph] +\newcounter{lsubsubparagraph}[subparagraph] +\newcounter{lequation} +% +% Redefine "*" forms of sectioning commands to increment their +% respective counters. +% +\let\Hpart=\part +\let\Hchapter=\chapter +\let\Hsection=\section +\let\Hsubsection=\subsection +\let\Hsubsubsection=\subsubsection +\let\Hparagraph=\paragraph +\let\Hsubparagraph=\subparagraph +\let\Hsubsubparagraph=\subsubparagraph + +% +% The following definitions are specific to LaTeX2e: +% (They must be commented out for LaTeX 2.09) +% +\def\part{\@ifstar{\stepcounter{lpart}\Hpart*}{\Hpart}} +\def\chapter{\@ifstar{\stepcounter{lchapter}\Hchapter*}{\Hchapter}} +\def\section{\@ifstar{\stepcounter{lsection}\Hsection*}{\Hsection}} +\def\subsection{\@ifstar{\stepcounter{lsubsection}\Hsubsection*}{\Hsubsection}} +\def\subsubsection{\@ifstar{\stepcounter{lsubsubsection}\Hsubsubsection*}{\Hsubsubsection}} +\def\paragraph{\@ifstar{\stepcounter{lparagraph}\Hparagraph*}{\Hparagraph}} +\def\subparagraph{\@ifstar{\stepcounter{lsubparagraph}\Hsubparagraph*}{\Hsubparagraph}} +\def\subsubparagraph{\@ifstar{\stepcounter{lsubsubparagraph}\Hsubsubparagraph*}{\Hsubsubparagraph}} +% +% Define a helper macro to dump a single \secounter command to a file. +% +\newcommand{\DumpPtr}[2]{% +\count255=\arabic{#1} \advance\count255 by \arabic{#2} +\immediate\write\ptrfile{% +\noexpand\setcounter{#1}{\number\count255}}} + +% +% Define a helper macro to dump all counters to the file. +% The value for each counter will be the sum of the l-counter +% actual LaTeX section counter. +% Also dump an \htmlhead{section-command}{section title} command +% to the file. +% + +\def\DumpCounters#1#2#3{\newwrite\ptrfile +\immediate\openout\ptrfile = #1.ptr +\DumpPtr{part}{lpart} +\ifx\Hchapter\undefined\relax\else\DumpPtr{chapter}{lchapter}\fi +\DumpPtr{section}{lsection} +\DumpPtr{subsection}{lsubsection} +\DumpPtr{subsubsection}{lsubsubsection} +\DumpPtr{paragraph}{lparagraph} +\DumpPtr{subparagraph}{lsubparagraph} +\DumpPtr{equation}{lequation} +\immediate\write\ptrfile{\noexpand\htmlhead{#2}{#3}} +\immediate\closeout\ptrfile} + +% +% Define the \segment{file}{section-command}{section-title} command, +% and its helper macros. This command does four things: +% 1) Begins a new LaTeX section; +% 2) Writes a list of section counters to file.ptr, each +% of which represents the sum of the LaTeX section +% counters, and the l-counters, defined above; +% 3) Write an \htmlhead{section-title} command to file.ptr; +% 4) Inputs file.tex. +% + +%%%%MG changed +\def\segment{\@ifstar{\@@htmls}{\@@html}} +\def\@@htmls#1#2#3{\csname #2\endcsname* {#3}% + \DumpCounters{#1}{#2*}{#3}\input{#1}} +\def\@@html#1#2#3{\csname #2\endcsname {#3}% + \DumpCounters{#1}{#2}{#3}\input{#1}} +%%%%MG + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Comment.sty version 2.0, 19 June 1992 +% selectively in/exclude pieces of text: the user can define new +% comment versions, and each is controlled separately. +% This style can be used with plain TeX or LaTeX, and probably +% most other packages too. +% +% Examples of use in LaTeX and TeX follow \endinput +% +% Author +% Victor Eijkhout +% Department of Computer Science +% University Tennessee at Knoxville +% 104 Ayres Hall +% Knoxville, TN 37996 +% USA +% +% eijkhout@cs.utk.edu +% +% Usage: all text included in between +% \comment ... \endcomment +% or \begin{comment} ... \end{comment} +% is discarded. The closing command should appear on a line +% of its own. No starting spaces, nothing after it. +% This environment should work with arbitrary amounts +% of comment. +% +% Other 'comment' environments are defined by +% and are selected/deselected with +% \includecomment{versiona} +% \excludecoment{versionb} +% +% These environments are used as +% \versiona ... \endversiona +% or \begin{versiona} ... \end{versiona} +% with the closing command again on a line of its own. +% +% Basic approach: +% to comment something out, scoop up every line in verbatim mode +% as macro argument, then throw it away. +% For inclusions, both the opening and closing comands +% are defined as noop +% +% Changed \next to \html@next to prevent clashes with other sty files +% (mike@emn.fr) +% Changed \html@next to \htmlnext so the \makeatletter and +% \makeatother commands could be removed (they were causing other +% style files - changebar.sty - to crash) (nikos@cbl.leeds.ac.uk) +% Changed \htmlnext back to \html@next... + +\makeatletter +\def\makeinnocent#1{\catcode`#1=12 } +\def\csarg#1#2{\expandafter#1\csname#2\endcsname} + +\def\ThrowAwayComment#1{\begingroup + \def\CurrentComment{#1}% + \let\do\makeinnocent \dospecials + \makeinnocent\^^L% and whatever other special cases + \endlinechar`\^^M \catcode`\^^M=12 \xComment} +{\catcode`\^^M=12 \endlinechar=-1 % + \gdef\xComment#1^^M{\def\test{#1} + \csarg\ifx{PlainEnd\CurrentComment Test}\test + \let\html@next\endgroup + \else \csarg\ifx{LaLaEnd\CurrentComment Test}\test + \edef\html@next{\endgroup\noexpand\end{\CurrentComment}} + \else \let\html@next\xComment + \fi \fi \html@next} +} +\makeatother + +\def\includecomment + #1{\expandafter\def\csname#1\endcsname{}% + \expandafter\def\csname end#1\endcsname{}} +\def\excludecomment + #1{\expandafter\def\csname#1\endcsname{\ThrowAwayComment{#1}}% + {\escapechar=-1\relax + \csarg\xdef{PlainEnd#1Test}{\string\\end#1}% + \csarg\xdef{LaLaEnd#1Test}{\string\\end\string\{#1\string\}}% + }} + +\excludecomment{comment} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%% RAW HTML +% +% Enclose raw HTML between a \begin{rawhtml} and \end{rawhtml}. +% The html environment ignores its body +% +\excludecomment{rawhtml} + +%%% HTML ONLY +% +% Enclose LaTeX constructs which will only appear in the +% HTML output and will be ignored by LaTeX with +% \begin{htmlonly} and \end{htmlonly} +% +\excludecomment{htmlonly} +% Shorter version +\newcommand{\html}[1]{} + + +%%% LaTeX ONLY +% Enclose LaTeX constructs which will only appear in the +% DVI output and will be ignored by latex2html with +%\begin{latexonly} and \end{latexonly} +% +\newenvironment{latexonly}{}{} +% Shorter version +\newcommand{\latex}[1]{#1} + +%%% HYPERREF +% Suggested by Eric M. Carol +% Similar to \ref but accepts conditional text. +% The first argument is HTML text which will become ``hyperized'' +% (underlined). +% The second and third arguments are text which will appear only in the paper +% version (DVI file), enclosing the fourth argument which is a reference to a label. +% +%e.g. \hyperref{using the tracer}{using the tracer (see Section}{)}{trace} +% where there is a corresponding \label{trace} +% +\newcommand{\hyperref}[4]{#2\ref{#4}#3} + +%%% HTMLREF +% Reference in HTML version only. +% Mix between \htmladdnormallink and \hyperref. +% First arg is text for in both versions, second is label for use in HTML +% version. +\newcommand{\htmlref}[2]{#1} + +%%% HTMLIMAGE +% This command can be used inside any environment that is converted +% into an inlined image (eg a "figure" environment) in order to change +% the way the image will be translated. The argument of \htmlimage +% is really a string of options separated by commas ie +% [scale=],[external],[thumbnail= +% The scale option allows control over the size of the final image. +% The ``external'' option will cause the image not to be inlined +% (images are inlined by default). External images will be accessible +% via a hypertext link. +% The ``thumbnail'' option will cause a small inlined image to be +% placed in the caption. The size of the thumbnail depends on the +% reduction factor. The use of the ``thumbnail'' option implies +% the ``external'' option. +% +% Example: +% \htmlimage{scale=1.5,external,thumbnail=0.2} +% will cause a small thumbnail image 1/5th of the original size to be +% placed in the final document, pointing to an external image 1.5 +% times bigger than the original. +% +\newcommand{\htmlimage}[1]{} + +%%% HTMLADDTONAVIGATION +% This command appends its argument to the buttons in the navigation +% panel. It is ignored by LaTeX. +% +% Example: +% \htmladdtonavigation{\htmladdnormallink +% {\htmladdimg{http://server/path/to/gif}} +% {http://server/path}} +\newcommand{\htmladdtonavigation}[1]{} + +\endinput \ No newline at end of file diff --git a/docs/linux.tex b/docs/linux.tex new file mode 100644 index 0000000000..42222867b1 --- /dev/null +++ b/docs/linux.tex @@ -0,0 +1,1963 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\chapter{The LINUX unit.} +This chapter describes the LINUX unit for Free Pascal. The unit was written +by Micha\"el van Canneyt. It works only on the Linux operating system. + +This chapter is divided in 2 sections: +\begin{itemize} +\item The first section lists all constants, types and variables, as listed +in the interface section of the LINUX unit. +\item The second section describes all procedures and functions in the LINUX +unit. +\end{itemize} + +\section{Type, Variable and Constant declarations} + +\subsection{Types} +\label{sec:types} +PGlob and TGlob are 2 types used in the \seef{Glob} function: +\begin{verbatim} +PGlob = ^TGlob; +TGlob = record + Name : PChar; + Next : PGlob; + end; +\end{verbatim} +The following types are used in the signal-processing procedures. +\begin{verbatim} +{$Packrecords 1} +SignalHandler = Procedure ( Sig : Integer); +PSignalHandler = ^SignalHandler; +SignalRestorer = Procedure; +PSignalrestorer = ^SignalRestorer; + +SigActionRec = Record + Sa_Handler : PSignalhandler; + Sa_Mask : Longint; + Sa_flags : Integer; + Sa_Restorer : PSignalRestorer; +end; +PSigActionRec = ^SigActionRec; +\end{verbatim} +Stat is used to store information about a file. It is defined in the +syscalls unit. + +\begin{verbatim} + stat = record + dev : word; + pad1 : word; + ino : longint; + mode : word; + nlink : word; + uid : word; + gid : word; + rdev : word; + pad2 : word; + size : longint; + blksze : Longint; + blocks : Longint; + atime : Longint; + unused1 : longint; + mtime : Longint; + unused2 : longint; + ctime : Longint; + unused3 : longint; + unused4 : longint; + unused5 : longint; + end; + \end{verbatim} + +Statfs is used to store information about a filesystem. It is defined in +the syscalls unit. +\begin{verbatim} + + statfs = record + fstype : longint; + bsize : longint; + blocks : longint; + bfree : longint; + bavail : longint; + files : longint; + ffree : longint; + fsid : longint; + namelen : longint; + spare : array [0..6] of longint; + end +\end{verbatim} +\var{Dir and PDir} are used in the \seef{OpenDir} and \seef{ReadDir} +functions. +\begin{verbatim} + TDir =record + fd : integer; + loc : longint; + size : integer; + buf : pdirent; + nextoff: longint; + dd_max : integer; + lock : pointer; + end; + PDir =^TDir; +\end{verbatim} +\var{Dirent, PDirent} are used in the \seef{ReadDir} function to return files in a directory. +\begin{verbatim} + PDirent = ^Dirent; + Dirent = Record + ino, + off : longint; + reclen : word; + name : string[255] + end; +\end{verbatim} +Termio and Termios are used with iotcl() calls for terminal handling. +\begin{verbatim} +Const NCCS = 19; + NCC = 8; + +Type termio = record + c_iflag, { input mode flags } + c_oflag, { output mode flags } + c_cflag, { control mode flags } + c_lflag : Word; { local mode flags } + c_line : Word; { line discipline - careful, only High byte in use} + c_cc : array [0..NCC-1] of char; { control characters } +end; + +termios = record + c_iflag, { input mode flags } + c_oflag, { output mode flags } + c_cflag, { control mode flags } + c_lflag : Cardinal; { local mode flags } + c_line : char; { line discipline } + c_cc : array [0..NCCS-1] of char; { control characters } +end; +\end{verbatim} +\var{Utimbuf} is used in the \seef{Utime} call to set access and modificaton time +of a file. +\begin{verbatim} +utimbuf = record + actime,modtime : Longint; + end; +\end{verbatim} +For the \seef{Select} call, the following 4 types are needed: +\begin{verbatim} +FDSet = Array [0..31] of longint; +PFDSet = ^FDSet; + +TimeVal = Record + sec,usec : Longint; +end; +PTimeVal = ^TimeVal; +\end{verbatim} +The \seep{Uname} function uses the \var{utsname} to return information about +the current kernel : +\begin{verbatim} +utsname =record + sysname,nodename,release, + version,machine,domainname : Array[0..64] of char; +end; +\end{verbatim} +Its elements are null-terminated C style strings, you cannot access them +directly ! + +\subsection{Variables} +\var{Linuxerror} is the variable in which the procedures in the linux unit +report errors. +\begin{verbatim} +LinuxError : Longint; +\end{verbatim} +\var{StdErr} Is a \var{Text} variable, corresponding to Standard Error or +diagnostic output. It is connected to file descriptor 2. It can be freely +used, and will be closed on exit. +\begin{verbatim} +StdErr : Text; +\end{verbatim} + +\subsection{Constants} +Constants for setting/getting process priorities : +\begin{verbatim} + Prio_Process = 0; + Prio_PGrp = 1; + Prio_User = 2; +\end{verbatim} +For testing access rights: +\begin{verbatim} + R_OK = 4; + W_OK = 2; + X_OK = 1; + F_OK = 0; +\end{verbatim} +For signal handling functions : +\begin{verbatim} + SA_NOCLDSTOP = 1; + SA_SHIRQ = $04000000; + SA_STACK = $08000000; + SA_RESTART = $10000000; + SA_INTERRUPT = $20000000; + SA_NOMASK = $40000000; + SA_ONESHOT = $80000000; + + SIG_BLOCK = 0; + SIG_UNBLOCK = 1; + SIG_SETMASK = 2; + + SIG_DFL = 0 ; + SIG_IGN = 1 ; + SIG_ERR = -1; + + SIGHUP = 1; + SIGINT = 2; + SIGQUIT = 3; + SIGILL = 4; + SIGTRAP = 5; + SIGABRT = 6; + SIGIOT = 6; + SIGBUS = 7; + SIGFPE = 8; + SIGKILL = 9; + SIGUSR1 = 10; + SIGSEGV = 11; + SIGUSR2 = 12; + SIGPIPE = 13; + SIGALRM = 14; + SIGTERM = 15; + SIGSTKFLT = 16; + SIGCHLD = 17; + SIGCONT = 18; + SIGSTOP = 19; + SIGTSTP = 20; + SIGTTIN = 21; + SIGTTOU = 22; + SIGURG = 23; + SIGXCPU = 24; + SIGXFSZ = 25; + SIGVTALRM = 26; + SIGPROF = 27; + SIGWINCH = 28; + SIGIO = 29; + SIGPOLL = SIGIO; + SIGPWR = 30; + SIGUNUSED = 31; +\end{verbatim} +For file control mechanism : +\begin{verbatim} + F_GetFd = 1; + F_SetFd = 2; + F_GetFl = 3; + F_SetFl = 4; + F_GetLk = 5; + F_SetLk = 6; + F_SetLkW = 7; + F_GetOwn = 8; + F_SetOwn = 9; +\end{verbatim} +For Terminal handling : +\begin{verbatim} + TCGETS = $5401 ; + TCSETS = $5402 ; + TCSETSW = $5403 ; + TCSETSF = $5404 ; + TCGETA = $5405 ; + TCSETA = $5406 ; + TCSETAW = $5407 ; + TCSETAF = $5408 ; + TCSBRK = $5409 ; + TCXONC = $540A ; + TCFLSH = $540B ; + TIOCEXCL = $540C ; + TIOCNXCL = $540D ; + TIOCSCTTY = $540E ; + TIOCGPGRP = $540F ; + TIOCSPGRP = $5410 ; + TIOCOUTQ = $5411 ; + TIOCSTI = $5412 ; + TIOCGWINSZ = $5413 ; + TIOCSWINSZ = $5414 ; + TIOCMGET = $5415 ; + TIOCMBIS = $5416 ; + TIOCMBIC = $5417 ; + TIOCMSET = $5418 ; + TIOCGSOFTCAR = $5419 ; + TIOCSSOFTCAR = $541A ; + FIONREAD = $541B ; + TIOCINQ = FIONREAD; + TIOCLINUX = $541C ; + TIOCCONS = $541D ; + TIOCGSERIAL = $541E ; + TIOCSSERIAL = $541F ; + TIOCPKT = $5420 ; + FIONBIO = $5421 ; + TIOCNOTTY = $5422 ; + TIOCSETD = $5423 ; + TIOCGETD = $5424 ; + TCSBRKP = $5425 ; + TIOCTTYGSTRUCT = $5426 ; + FIONCLEX = $5450 ; + FIOCLEX = $5451 ; + FIOASYNC = $5452 ; + TIOCSERCONFIG = $5453 ; + TIOCSERGWILD = $5454 ; + TIOCSERSWILD = $5455 ; + TIOCGLCKTRMIOS = $5456 ; + TIOCSLCKTRMIOS = $5457 ; + TIOCSERGSTRUCT = $5458 ; + TIOCSERGETLSR = $5459 ; + TIOCSERGETMULTI = $545A ; + TIOCSERSETMULTI = $545B ; + + TIOCMIWAIT = $545C ; + TIOCGICOUNT = $545D ; + + TIOCPKT_DATA = 0; + TIOCPKT_FLUSHREAD = 1; + TIOCPKT_FLUSHWRITE = 2; + TIOCPKT_STOP = 4; + TIOCPKT_START = 8; + TIOCPKT_NOSTOP = 16; + TIOCPKT_DOSTOP = 32; +\end{verbatim} +Other than that, all constants for setting the speed and control flags of a +terminal line, as described in the \seem{termios}{2} man +page, are defined in the linux unit. It would take too much place to list +them here. + +To check the \var{mode} field of a \var{stat} record, you ca use the +following constants : +\begin{verbatim} + { Constants to check stat.mode } + STAT_IFMT = $f000; {00170000} + STAT_IFSOCK = $c000; {0140000} + STAT_IFLNK = $a000; {0120000} + STAT_IFREG = $8000; {0100000} + STAT_IFBLK = $6000; {0060000} + STAT_IFDIR = $4000; {0040000} + STAT_IFCHR = $2000; {0020000} + STAT_IFIFO = $1000; {0010000} + STAT_ISUID = $0800; {0004000} + STAT_ISGID = $0400; {0002000} + STAT_ISVTX = $0200; {0001000} + { Constants to check permissions } + STAT_IRWXO = $7; + STAT_IROTH = $4; + STAT_IWOTH = $2; + STAT_IXOTH = $1; + + STAT_IRWXG = STAT_IRWXO shl 3; + STAT_IRGRP = STAT_IROTH shl 3; + STAT_IWGRP = STAT_IWOTH shl 3; + STAT_IXGRP = STAT_IXOTH shl 3; + + STAT_IRWXU = STAT_IRWXO shl 6; + STAT_IRUSR = STAT_IROTH shl 6; + STAT_IWUSR = STAT_IWOTH shl 6; + STAT_IXUSR = STAT_IXOTH shl 6; +\end{verbatim} +You can test the type of a filesystem returned by a \seef{FSStat} call with +the following constants: +\begin{verbatim} + fs_old_ext2 = $ef51; + fs_ext2 = $ef53; + fs_ext = $137d; + fs_iso = $9660; + fs_minix = $137f; + fs_minix_30 = $138f; + fs_minux_V2 = $2468; + fs_msdos = $4d44; + fs_nfs = $6969; + fs_proc = $9fa0; + fs_xia = $012FD16D; +\end{verbatim} + + +\section{Functions and procedures} + +%\function{Name}{arguments}{return type}{explain}{errors}{refs} +%\procedure{Name}{arguments}{explain}{errors}{refs} +%\function{}{()}{}{}{}{}{} +%\procedure{}{}{}{}{}{} +\function{GetEpochTime}{}{longint} +{ +returns the number of seconds since 00:00:00 gmt, january 1, 1970. +it is adjusted to the local time zone, but not to DST. +} +{no errors} +{\seep{EpochToLocal}, \seep{GetTime}, \seem{time}{2}} + +\input{linuxex/ex1.tex} + +\procedure +{EpochToLocal} +{(Epoch : Longint; var Year,Month,Day,Hour,Minute,Second : Word)} +{ +Converts the epoch time (=Number of seconds since 00:00:00 , January 1, +1970, corrected for your time zone ) to local date and time. +} +{None} +{\seef{GetEpochTime}, \seef{LocalToEpoch}, \seep{GetTime},\seep{GetDate} } + +\input{linuxex/ex3.tex} + +\function{LocalToEpoch}{(Year,Month,Day,Hour,Minute,Second : Word)}{longint} +{ +Converts the Local time to epoch time (=Number of seconds since 00:00:00 , January 1, +1970 ). +} +{None} +{\seef{GetEpochTime}, \seep{EpochToLocal}, \seep{GetTime},\seep{GetDate} } + +\input{linuxex/ex4.tex} + +\procedure{GetTime} +{ (Var Hour,Minute, Second : Word) } +{ +Returns the current time of the day. +} +{None} +{\seef{GetEpochTime}, \seep{GetDate}, \seep{EpochToLocal} } + +\input{linuxex/ex5.tex} + +\procedure{GetDate} +{ (Var Year, Month, Day : Word) } +{ +Returns the current day. +} +{None} +{\seef{GetEpochTime}, \seep{GetTime}, \seep{EpochToLocal} } + +\input{linuxex/ex6.tex} + +\procedure{Execve} +{(Path : pathstr; args,ep : ppchar)} +{ +Replaces the currently running program with the program, specified in +\var{path}. +It gives the program the options in \var{args}, and the environment in +\var{ep}. They are pointers to an array of pointers to null-terminated +strings. The last pointer in this array should be nil. + +On success, \var{execve} does not return. +} +{Errors are reported in \var{LinuxError}: +\begin{description} +\item[eacces] File is not a regular file, or has no execute permission. +A compononent of the path has no search permission. +\item[sys\_ eperm] The file system is mounted \textit{noexec}. +\item[sys\_ e2big] Argument list too big. +\item[sys\_ enoexec] The magic number in the file is incorrect. +\item[sys\_ enoent] The file does not exist. +\item[sys\_ enomem] Not enough memory for kernel. +\item[sys\_ enotdir] A component of the path is not a directory. +\item[sys\_ eloop] The path contains a circular reference (via symlinks). +\end{description}} +{\seep{Execve}, \seep{Execv}, \seep{Execvp} \seep{Execle}, +\seep{Execl}, \seep{Execlp}, \seef {Fork}, \seem{execve}{2} } + +\input{linuxex/ex7.tex} + +\procedure{Execv} +{(Path : pathstr; args : ppchar)} +{ +Replaces the currently running program with the program, specified in +\var{path}. +It gives the program the options in \var{args}. +This is a pointer to an array of pointers to null-terminated +strings. The last pointer in this array should be nil. +The current environment is passed to the program. + +On success, \var{execv} does not return. +} +{Errors are reported in \var{LinuxError}: +\begin{description} +\item[sys\_eacces] File is not a regular file, or has no execute permission. +A compononent of the path has no search permission. +\item[sys\_eperm] The file system is mounted \textit{noexec}. +\item[sys\_e2big] Argument list too big. +\item[sys\_enoexec] The magic number in the file is incorrect. +\item[sys\_enoent] The file does not exist. +\item[sys\_enomem] Not enough memory for kernel. +\item[sys\_enotdir] A component of the path is not a directory. +\item[sys\_eloop] The path contains a circular reference (via symlinks). +\end{description}} +{\seep{Execve}, \seep{Execvp}, \seep{Execle}, +\seep{Execl}, \seep{Execlp}, \seef {Fork}, \seem{execv}{3} } + +\input{linuxex/ex8.tex} + +\procedure{Execvp} +{(Path : pathstr; args : ppchar)} +{ +Replaces the currently running program with the program, specified in +\var{path}. The executable in \var{path} is searched in the path, if it isn't +an absolute filename. +It gives the program the options in \var{args}. This is a pointer to an array of pointers to null-terminated +strings. The last pointer in this array should be nil. +The current environment is passed to the program. + +On success, \var{execvp} does not return. +} +{Errors are reported in \var{LinuxError}: +\begin{description} +\item[sys\_eacces] File is not a regular file, or has no execute permission. +A compononent of the path has no search permission. +\item[sys\_eperm] The file system is mounted \textit{noexec}. +\item[sys\_e2big] Argument list too big. +\item[sys\_enoexec] The magic number in the file is incorrect. +\item[sys\_enoent] The file does not exist. +\item[sys\_enomem] Not enough memory for kernel. +\item[sys\_enotdir] A component of the path is not a directory. +\item[sys\_eloop] The path contains a circular reference (via symlinks). +\end{description}} +{\seep{Execve}, \seep{Execv}, \seep{Execle}, +\seep{Execl}, \seep{Execlp}, \seef {Fork}, \seem{execvp}{3} } + +\input{linuxex/ex9.tex} + +\procedure{Execl} +{(Path : pathstr)} +{ +Replaces the currently running program with the program, specified in +\var{path}. Path is split into a command and it's options. +The executable in \var{path} is NOT searched in the path. +The current environment is passed to the program. + +On success, \var{execl} does not return. +} +{Errors are reported in \var{LinuxError}: +\begin{description} +\item[sys\_eacces] File is not a regular file, or has no execute permission. +A compononent of the path has no search permission. +\item[sys\_eperm] The file system is mounted \textit{noexec}. +\item[sys\_e2big] Argument list too big. +\item[sys\_enoexec] The magic number in the file is incorrect. +\item[sys\_enoent] The file does not exist. +\item[sys\_enomem] Not enough memory for kernel, or to split command line. +\item[sys\_enotdir] A component of the path is not a directory. +\item[sys\_eloop] The path contains a circular reference (via symlinks). +\end{description}} +{\seep{Execve}, \seep{Execv}, \seep{Execvp}, \seep{Execle}, + \seep{Execlp}, \seef {Fork}, \seem{execvp}{3} } + +\input{linuxex/ex10.tex} + +\procedure{Execle} +{(Path : pathstr, Ep : ppchar)} +{ +Replaces the currently running program with the program, specified in +\var{path}. Path is split into a command and it's options. +The executable in \var{path} is searched in the path, if it isn't +an absolute filename. +The environment in \var{ep} is passed to the program. + +On success, \var{execle} does not return. +} +{Errors are reported in \var{LinuxError}: +\begin{description} +\item[sys\_eacces] File is not a regular file, or has no execute permission. +A compononent of the path has no search permission. +\item[sys\_eperm] The file system is mounted \textit{noexec}. +\item[sys\_e2big] Argument list too big. +\item[sys\_enoexec] The magic number in the file is incorrect. +\item[sys\_enoent] The file does not exist. +\item[sys\_enomem] Not enough memory for kernel, or to split command line. +\item[sys\_enotdir] A component of the path is not a directory. +\item[sys\_eloop] The path contains a circular reference (via symlinks). +\end{description}} +{\seep{Execve}, \seep{Execv}, \seep{Execvp}, +\seep{Execl}, \seep{Execlp}, \seef {Fork}, \seem{execvp}{3} } + +\input{linuxex/ex11.tex} + +\procedure{Execlp} +{(Path : pathstr)} +{ +Replaces the currently running program with the program, specified in +\var{path}. Path is split into a command and it's options. +The executable in \var{path} is searched in the path, if it isn't +an absolute filename. +The current environment is passed to the program. + +On success, \var{execlp} does not return. +} +{Errors are reported in \var{LinuxError}: +\begin{description} +\item[sys\_eacces] File is not a regular file, or has no execute permission. +A compononent of the path has no search permission. +\item[sys\_eperm] The file system is mounted \textit{noexec}. +\item[sys\_e2big] Argument list too big. +\item[sys\_enoexec] The magic number in the file is incorrect. +\item[sys\_enoent] The file does not exist. +\item[sys\_enomem] Not enough memory for kernel, or to split command line. +\item[sys\_enotdir] A component of the path is not a directory. +\item[sys\_eloop] The path contains a circular reference (via symlinks). +\end{description}} +{\seep{Execve}, \seep{Execv}, \seep{Execvp}, \seep{Execle}, +\seep{Execl}, \seef {Fork}, \seem{execvp}{3} } + +\input{linuxex/ex12.tex} + +\function{Fork}{}{Longint} +{ +Fork creates a child process which is a copy of the parent process. + +Fork returns the process ID in the parent process, and zero in the child's +process. (you can get the parent's PID with \seef{GetPPid}). +} +{On error, -1 is returned to the parent, and no child is created. +\begin{description} +\item [sys\_eagain] Not enough memory to create child process. +\end{description} +} +{\seep{Execve}, \seem{fork}{2}} + +\input{linuxex/ex14.tex} + +\procedure{Nice}{( N : Integer)} +{Nice adds \var{-N} to the priority of the running process. The lower the +priority numerically, the less the process is favored. + +Only the superuser can specify a negative \var{N}, i.e. increase the rate at +which the process is run. +} +{ Errors are returned in \var{LinuxError} +\begin{description} +\item [sys\_eperm] A non-superuser tried to specify a negative \var{N}, i.e. +do a priority increase. +\end{description} +}{\seef{GetPriority}, \seef{SetPriority}, \seem{Nice}{2}} + +\input{linuxex/ex15.tex} + +\function{GetPriority}{(Which,Who : Integer)}{Integer} +{ +GetPriority returns the priority with which a process is running. +Which process(es) is determined by the \var{Which} and \var{Who} variables. +\var{Which} can be one of the pre-defined \var{Prio\_Process, Prio\_PGrp, +Prio\_User}, in which case \var{Who} is the process ID, Process group ID or +User ID, respectively. +} +{ + Error checking must be done on LinuxError, since a priority can be negative. + \begin{description} + \item[sys\_esrch] No process found using \var{which} and \var{who}. + \item[sys\_einval] \var{Which} was not one of \var{Prio\_Process, Prio\_Grp +or Prio\_User}. + \end{description} + } +{\seef{SetPriority}, \seep{Nice}, \seem{Getpriority}{2}} + +For an example, see \seep{Nice}. + +\function{SetPriority}{(Which,Who,Prio : Integer)}{Integer} +{ +SetPriority sets the priority with which a process is running. +Which process(es) is determined by the \var{Which} and \var{Who} variables. +\var{Which} can be one of the pre-defined \var{Prio\_Process, Prio\_PGrp, +Prio\_User}, in which case \var{Who} is the process ID, Process group ID or +User ID, respectively. + +\var{Prio} is a value in the range -20 to 20. +} +{ + Error checking must be done on LinuxError, since a priority can be negative. + \begin{description} + \item[sys\_esrch] No process found using \var{which} and \var{who}. + \item[sys\_einval] \var{Which} was not one of \var{Prio\_Process, Prio\_Grp +or Prio\_User}. + \item[sys\_eperm] A process was found, but neither its effective or real + user ID match the effective user ID of the caller. + \item [sys\_eacces] A non-superuser tried to a priority increase. + \end{description} + } +{\seef{GetPriority}, \seep{Nice}, \seem{Setpriority}{2}} + +For an example, see \seep{Nice}. + +\function{GetPid}{}{Longint} +{ Get the Process ID of the currently running process.} +{None.} +{\seef{GetPPid}, \seem{getpid}{2}} + +\input{linuxex/ex16.tex} + + +\function{GetPPid}{}{Longint} +{ Get the Process ID of the parent process.} +{None.} +{\seef{GetPid}, \seem{getppid}{2}} + +\input{linuxex/ex16.tex} + +\function{GetUid}{}{Longint} +{ Get the real user ID of the currently running process.} +{None.} +{\seef{GetEUid}, \seem{getuid}{2} } + +\input{linuxex/ex17.tex} + +\function{GetEUid}{}{Longint} +{ Get the effective user ID of the currently running process.} +{None.} +{\seef{GetEUid}, \seem{geteuid}{2} } + +\input{linuxex/ex17.tex} + +\function{GetGid}{}{Longint} +{ Get the real group ID of the currently running process.} +{None.} +{\seef{GetEGid}, \seem{getgid}{2} } + +\input{linuxex/ex18.tex} + +\function{GetEGid}{}{Longint} +{ Get the effective group ID of the currently running process.} +{None.} +{\seef{GetGid}, \seem{getegid}{2} } + +\input{linuxex/ex18.tex} + +\function{Link}{(OldPath,NewPath : pathstr)}{Boolean} +{\var{Link} makes \var{NewPath} point to the same file als \var{OldPath}. The two files +then have the same inode number. This is known as a 'hard' link. + +The function returns \var{True} if the call was succesfull, \var{False} if the call +failed. +} +{ Errors are returned in \var{LinuxError}. +\begin{description} +\item[sys\_exdev] \var {OldPath} and \var {NewPath} are not on the same +filesystem. +\item[sys\_eperm] The filesystem containing oldpath and newpath doesn't +support linking files. +\item[sys\_eaccess] Write access for the directory containing \var{Newpath} +is disallowed, or one of the directories in \var{OldPath} or {NewPath} has no +search (=execute) permission. +\item[sys\_enoent] A directory entry in \var{OldPath} or \var{NewPath} does +not exist or is a symbolic link pointing to a non-existent directory. +\item[sys\_enotdir] A directory entry in \var{OldPath} or \var{NewPath} is +nor a directory. +\item[sys\_enomem] Insufficient kernel memory. +\item[sys\_erofs] The files are on a read-only filesystem. +\item[sys\_eexist] \var{NewPath} already exists. +\item[sys\_emlink] \var{OldPath} has reached maximal link count. +\item[sys\_eloop] \var{OldPath} or \var{NewPath} has a reference to a circular +symbolic link, i.e. a symbolic link, whose expansion points to itself. +\item[sys\_enospc] The device containing \var{NewPath} has no room for anothe +entry. +\item[sys\_eperm] \var{OldPath} points to . or .. of a directory. +\end{description} +} +{\seef{SymLink}, \seef{UnLink}, \seem{Link}{2} } + +\input{linuxex/ex21.tex} + +\function{SymLink}{(OldPath,NewPath : pathstr)}{Boolean} +{\var{SymLink} makes \var{Newpath} point to the file in \var{OldPath}, which doesn't +necessarily exist. The two files DO NOT have the same inode number. +This is known as a 'soft' link. +The permissions of the link are irrelevant, as they are not used when +following the link. Ownership of the file is only checked in case of removal +or renaming of the link. + +The function returns \var{True} if the call was succesfull, \var{False} if the call +failed. +} +{ Errors are returned in \var{LinuxError}. +\begin{description} +\item[sys\_eperm] The filesystem containing oldpath and newpath doesn't +support linking files. +\item[sys\_eaccess] Write access for the directory containing \var{Newpath} +is disallowed, or one of the directories in \var{OldPath} or {NewPath} has no +search (=execute) permission. +\item[sys\_enoent] A directory entry in \var{OldPath} or \var{NewPath} does +not exist or is a symbolic link pointing to a non-existent directory. +\item[sys\_enotdir] A directory entry in \var{OldPath} or \var{NewPath} is +nor a directory. +\item[sys\_enomem] Insufficient kernel memory. +\item[sys\_erofs] The files are on a read-only filesystem. +\item[sys\_eexist] \var{NewPath} already exists. +\item[sys\_eloop] \var{OldPath} or \var{NewPath} has a reference to a circular +symbolic link, i.e. a symbolic link, whose expansion points to itself. +\item[sys\_enospc] The device containing \var{NewPath} has no room for anothe +entry. +\end{description} +} +{\seef{Link}, \seef{UnLink}, \seem{Symlink}{2} } + +\input{linuxex/ex22.tex} + +\function{UnLink}{(Path : pathstr)}{Boolean} +{ +\var{UnLink} decreases the link count on file \var{Path}. If the link count is zero, the +file is removed from the disk. + +The function returns \var{True} if the call was succesfull, \var{False} if the call +failed. +} +{ Errors are returned in \var{LinuxError}. +\begin{description} +\item[sys\_eaccess] You have no write access right in the directory +containing \var{Path}, or you have no search permission in one of the +directory components of \var{Path}. +\item[sys\_eperm] The directory containing pathname has the sticky-bit +set and the process's effective uid is neither the uid of the +file to be deleted nor that of the directory containing it. +\item[sys\_enoent] A component of the path doesn't exist. +\item[sys\_enotdir] A directory component of the path is not a directory. +\item[sys\_eisdir] \var{Path} refers to a directory. +\item[sys\_enomem] Insufficient kernel memory. +\item[sys\_erofs] \var{Path} is on a read-only filesystem. +\end{description} +} +{\seef{Link}, \seef{SymLink}, \seem{Unlink}{2} } + +For an example, see \seef{Link}. + +\function{Chown}{(Path : Pathstr;NewUid,NewGid : Longint)}{Boolean} +{ \var{Chown} sets the User ID and Group ID of the file in \var{Path} to \var{NewUid, +NewGid}. + +The function returns \var{True} if the call was succesfull, \var{False} if the call +failed. +} +{ +Errors are returned in \var{LinuxError}. +\begin{description} +\item[sys\_eperm] The effective UID doesn't match the ownership of the file, +and is not zero. Owner or group were not specified correctly. +\item[sys\_eaccess] One of the directories in \var{Path} has no +search (=execute) permission. +\item[sys\_enoent] A directory entry in \var{Path} does +not exist or is a symbolic link pointing to a non-existent directory. +\item[sys\_enotdir] A directory entry in \var{OldPath} or \var{NewPath} is +nor a directory. +\item[sys\_enomem] Insufficient kernel memory. +\item[sys\_erofs] The file is on a read-only filesystem. +\item[sys\_eloop] \var{Path} has a reference to a circular +symbolic link, i.e. a symbolic link, whose expansion points to itself. +\end{description} +} +{\seef{Chmod}, \seef{Access}, \seem{Chown}(2)} + +\input{linuxex/ex24.tex} + +\function{Chmod}{(Path : Pathstr;NewMode : Longint)}{Boolean} +{ \var{Chmod} +Sets the Mode bits of the file in \var{Path} to \var{NewMode}. Newmode can be +specified by 'or'-ing the following: +\begin{description} +\item[S\_ISUID] Set user ID on execution. +\item[S\_ISGID] Set Group ID on execution. +\item[S\_ISVTX] Set sticky bit. +\item[S\_IRUSR] Read by owner. +\item[S\_IWUSR] Write by owner. +\item[S\_IXUSR] Execute by owner. +\item[S\_IRGRP] Read by group. +\item[S\_IWGRP] Write by group. +\item[S\_IXGRP] Execute by group. +\item[S\_IROTH] Read by others. +\item[S\_IWOTH] Write by others. +\item[S\_IXOTH] Execute by others. +\item[S\_IRWXO] Read, write, execute by others. +\item[S\_IRWXG] Read, write, execute by groups. +\item[S\_IRWXU] Read, write, execute by user. +\end{description} +} +{ +Errors are returned in \var{LinuxError}. +\begin{description} +\item[sys\_eperm] The effective UID doesn't match the ownership of the file, +and is not zero. Owner or group were not specified correctly. +\item[sys\_eaccess] One of the directories in \var{Path} has no +search (=execute) permission. +\item[sys\_enoent] A directory entry in \var{Path} does +not exist or is a symbolic link pointing to a non-existent directory. +\item[sys\_enotdir] A directory entry in \var{OldPath} or \var{NewPath} is +nor a directory. +\item[sys\_enomem] Insufficient kernel memory. +\item[sys\_erofs] The file is on a read-only filesystem. +\item[sys\_eloop] \var{Path} has a reference to a circular +symbolic link, i.e. a symbolic link, whose expansion points to itself. +\end{description} +} +{\seef{Chown}, \seef{Access}, \seem{Chmod}(2)} + +\input{linuxex/ex23.tex} + +\function{Utime}{(path : pathstr; utim : utimbuf)}{Boolean} +{ +\var{Utime} sets the access and modification times of a file. +the \var{utimbuf} record contains 2 fields, \var{actime}, and \var{modtime}, +both of type Longint. They should be filled with an epoch-like time, +specifying, respectively, the last access time, and the last modification +time. + +For some filesystem (most notably, FAT), these times are the same. +} +{Errors are returned in \var{LinuxError}. +\begin{description} +\item[sys\_eaccess] One of the directories in \var{Path} has no +search (=execute) permission. +\item[sys\_enoent] A directory entry in \var{Path} does +not exist or is a symbolic link pointing to a non-existent directory. +\end{description} +Other errors may occur, but aren't documented. +} +{\seef{GetEpochTime}, \seef{Chown}, \seef{Access}, \seem{utime}(2)} + +\input{linuxex/ex25.tex} + +\function{Umask}{(Mask : Integer)}{Integer} +{ +Change the file creation mask for the current user to \var{Mask}. The +current mask is returned. +} +{None} +{\seef{Chmod}, \seem{Umask}{2}} + +\input{linuxex/ex27.tex} + +\function{Access}{(Path : Pathstr; Mode : integer)}{Boolean} +{ +Tests user's access rights on the specified file. Mode is a mask existing of +one or more of +\begin{description} +\item[R\_OK] User has read rights. +\item[W\_OK] User has write rights. +\item[X\_OK] User has execute rights. +\item[F\_OK] User has search rights in the directory where the file is. +\end{description} +The test is done with the real user ID, instead of the effective user ID. + +If access is denied, or an error occurred, false is returned. +} +{ \var{LinuxError} is used to report errors: +\begin{description} +\item[sys\_eaccess] The requested access is denied, either to the file or one +of the directories in its path. +\item[sys\_einval] \var{Mode} was incorrect. +\item[sys\_enoent] A directory component in \var{Path} doesn't exist or is a +dangling symbolic link. +\item[sys\_enotdir] A directory component in \var{Path} is not a directory. +\item[sys\_enomem] Insufficient kernel memory. +\item[sys\_eloop] \var{Path} has a circular symbolic link. +\end{description} +} +{\seef{Chown}, \seef{Chmod}, \seem{Access}{2} } + +\input{linuxex/ex26.tex} + +\function{FStat}{(Path : Pathstr; Var Info : stat)}{Boolean} +{ +\var{FStat} gets information about the file specified in \var{Path}, and stores it in +\var{Info}, which is of type \var{stat}. + +The function returns \var{True} if the call was succesfull, \var{False} if the call +failed. +} +{ \var{LinuxError} is used to report errors. +\begin{description} +\item[sys\_enoent] \var{Path} does not exist. +\end{description} +} +{\seef{FSStat}, \seef{LStat}, \seem{stat}{2}} + +\input{linuxex/ex28.tex} + +\function{LStat}{(Path : Pathstr; Var Info : stat)}{Boolean} +{ +\var{LStat} gets information about the link specified in \var{Path}, and stores it in +\var{Info}, which is of type \var{stat}. Contrary to \var{FStat}, it stores +information about the link, not about the file the link points to. + +The function returns \var{True} if the call was succesfull, \var{False} if the call +failed. +} +{ \var{LinuxError} is used to report errors. +\begin{description} +\item[sys\_enoent] \var{Path} does not exist. +\end{description} +} +{\seef{FStat}, \seef{FSStat}, \seem{stat}{2}} + +\input{linuxex/ex29.tex} + +\function{FSStat}{(Path : Pathstr; Var Info : statfs)}{Boolean} +{ Return in \var{Info} information about the filesystem on which the file +\var{Path} resides. Info is of type \var{statfs}. + +The function returns \var{True} if the call was succesfull, \var{False} if the call +failed. +} +{ \var{LinuxError} is used to report errors. +\begin{description} +\item[sys\_enotdir] A component of \var{Path} is not a directory. +\item[sys\_einval] Invalid character in \var{Path}. +\item[sys\_enoent] \var{Path} does not exist. +\item[sys\_eaccess] Search permission is denied for component in +\var{Path}. +\item[sys\_eloop] A circular symbolic link was encountered in \var{Path}. +\item[sys\_eio] An error occurred while reading from the filesystem. +\end{description} +} +{\seef{FStat}, \seef{LStat}, \seem{statfs}{2}} + +\input{linuxex/ex30.tex} + +\procedure{IOCtl}{(Handle,Ndx: Longint; Data: Pointer)} +{ +This is a general interface to the Unix/ \linux ioctl call. +It performs various operations on the filedescriptor \var{Handle}. +\var{Ndx} describes the operation to perform. +\var{Data} points to data needed for the \var{Ndx} function. +The structure of this data is function-dependent, so we don't elaborate on +this here. + +For more information on this, see various manual pages under linux. +} +{ +Errors are reported in LinuxError. They are very dependent on the used +function, that's why we don't list them here +} +{\seem{ioctl}{2}} + +\input{linuxex/ex54.tex} + +\function{IsATTY}{(var f)}{Boolean}; +{ +Check if the filehandle described by \var{f} is a terminal. +f can be of type +\begin{enumerate} +\item \var{longint} for file handles; +\item \var{Text} for \var{text} variables such as \var{input} etc. +\end{enumerate} + +Returns \var{True} if \var{f} is a terminal, \var{False} otherwise. +} +{No errors are reported} +{\seep{IOCtl},\seef{TTYName}} + +\function{TTYName}{(var f)}{String} +{ +Returns the name of the terminal pointed to by \var{f}. \var{f} +must be a terminal. \var{f} can be of type: +\begin{enumerate} +\item \var{longint} for file handles; +\item \var{Text} for \var{text} variables such as \var{input} etc. +\end{enumerate} +} +{ Returns an empty string in case of an error. \var{Linuxerror} may be set + to indicate what error occurred, but this is uncertain.} +{\seef{IsATTY},\seep{IOCtl}} + +\function{FExpand}{(Const Path: Pathstr)}{pathstr} +{ Expands \var {Path} to a full path, starting from root, +eliminating directory references such as . and .. from the result. +} +{None} +{\seef{BaseName},\seef{DirName} } + +\input{linuxex/ex45.tex} + +\function{FSearch}{(Path : pathstr;DirList : string)}{Pathstr} +{ Searches in \var{DirList}, a colon separated list of directories, +for a file named \var{Path}. It then returns a path to the found file.} +{An empty string if no such file was found.} +{\seef{BaseName}, \seef{DirName}, \seef{FExpand} } + +\input{linuxex/ex46.tex} + +\function{BaseName}{(Const Path;Suf : Pathstr)}{Pathstr} +{Returns the filename part of \var{Path}, stripping off \var{Suf} if it +exists. + +The filename part is the whole name if \var{Path} contains no slash, +or the part of \var{Path} after the last slash. + +The last character of the result is not a slash, unless the directory is the +root directory. +} +{None.} +{\seef{DirName}, \seef{FExpand}, \seem{Basename}{1}} + +\input{linuxex/ex48.tex} + +\function{DirName}{(Const Path : Pathstr)}{Pathstr} +{Returns the directory part of \var{Path}. + +The directory is the part of \var{Path} before the last slash, +or empty if there is no slash. + +The last character of the result is not a slash, unless the directory is the +root directory. +} +{None.} +{\seef{BaseName}, \seef{FExpand}, \seem{Dirname}{1}} + +\input{linuxex/ex47.tex} + +\function{Glob}{(Const Path : Pathstr)}{PGlob} +{ +Glob returns a pointer to a glob structure which contains all filenames which +exist and match the pattern in \var{Path}. + +The pattern can contain wildcard characters, which have their +usual meaning. + +The pglob structure is defined as : +Some more text. +} +{ Returns nil on error, and \var{LinuxError} is set. +\begin{description} +\item[sys\_enomem] No memory on heap for glob structure. +\item[others] As returned by the opendir call, and sys\_readdir. +\end{description} +} +{\seep{GlobFree}, \seem{Glob}{3} } + +\input{linuxex/ex49.tex} + + \procedure{GlobFree}{(Var P : Pglob)} + {Releases the memory, occupied by a pglob structure. \var{P} is set to nil.}{None} + { \seef{Glob} } + +For an example, see \seef{Glob}. + +\procedure{AssignPipe}{(Pipe\_in, Pipe\_out : Text)} +{\var{AssignePipe} creates a pipe, i.e. two file objects, one for input, one for output. +What is written to \var{Pipe\_out}, can be read from \var{Pipe\_in}. +Reading and writing happens through the usual \var{Readln(Pipe\_in,...)} and +\var{Writeln (Pipe\_out,...)} procedures. +} +{ \var{LinuxError} is used to report errors: +\begin{description} +\item[sys\_emfile] Too many file descriptors for this process. +\item[sys\_enfile] The system file table is full. +\end{description} +} +{\seep{POpen}, \seef{MkFifo}, \seem{pipe}{2}} + +\input{linuxex/ex36.tex} + +\function{MkFifo}{(PathName: String; Mode : Longint)}{Boolean} +{\var{MkFifo} creates named a named pipe in the filesystem, with name +\var{PathName} and mode {Mode}. +} +{ \var{LinuxError} is used to report errors: +\begin{description} +\item[sys\_emfile] Too many file descriptors for this process. +\item[sys\_enfile] The system file table is full. +\end{description} +} +{\seep{POpen}, \seef{MkFifo}, \seem{mkfifo}{4}} + + +\procedure{AssignStream}{(StreamIn,StreamOut : Text; Const prog : String)} +{\var{AssignStream} creates a 2 pipes, i.e. two file objects, one for input, one for +output, the other ends of these pipes are connected to standard input and and +output of \var{Prog}. \var{Prog} is the name of a program (including path) +with options, which will be executed. +What is written to \var{StreamOut}, will go to the standard input of +\var{Prog}. Whatever is written by \var{Prog} to it's standard output be read from +\var{StreamIn}. +Reading and writing happens through the usual \var{Readln(StreamIn,...)} and +\var{Writeln (StreamOut,...)} procedures. +} +{ \var{LinuxError} is used to report errors: +\begin{description} +\item[sys\_emfile] Too many file descriptors for this process. +\item[sys\_enfile] The system file table is full. +\end{description} +Other errors include the ones by the fork and exec programs +} +{\seep{AssignPipe}, \seep{POpen},\seem{pipe}{2}} + +\input{linuxex/ex38.tex} + +\procedure {POpen}{(F : Text; Cmd : pathstr; rw : char)} +{ Popen runs the command specified in \var{Cmd}, + and redirects the standard in or output of the +command to the other end of the pipe \var{F}. The parameter \var{rw} +indicates the direction of the pipe. If it is set to \var{'W'}, then F can +be used to write data, which will then be read by the command from stdinput. +If it is set to \var{'R'}, then the standard output of the command can be +read from \var{F}. \var{F} should be reset or rewritten. +.} +{Errors are reported in \var{LinuxError} and are essentially those of the +Execve, Dup and AssignPipe commands. +} +{\seep{AssignPipe}, \seem{popen}{3}} + +\input{linuxex/ex37.tex} + +\function{Fcntl}{(Fd : text, Cmd : Integer)}{Integer} +{ +Read a file's attributes. \var{Fd} is an assigned file. +\var{Cmd} speciefies what to do, and is one of the following: +\begin{description} +\item[F\_GetFd] Read the close\_on\_exec flag. If the low-order bit is 0, then +the file will remain open across execve calls. +\item[F\_GetFl] Read the descriptor's flags. +\item[F\_GetOwn] Get the Process ID of the owner of a socket. +\end{description} +} +{ +\var{LinuxError} is used to report errors. +\begin{description} +\item[sys\_ebadf] \var{Fd} has a bad file descriptor. +\end{description} +} +{\seep{Fcntl}, \seem{Fcntl}{2} } + +\procedure{Fcntl}{(Fd : text, Cmd : Integer; Arg : longint)} +{ +Read or Set a file's attributes. \var{Fd} is an assigned file. +\var{Cmd} speciefies what to do, and is one of the following: +\begin{description} +\item[F\_SetFd] Set the close\_on\_exec flag of \var{Fd}. (only the least +siginificant bit is used). +\item[F\_GetLk] Return the \var{flock} record that prevents this process from +obtaining the lock, or set the \var{l\_type} field of the lock of there is no +obstruction. Arg is a pointer to a flock record. +\item[F\_SetLk] Set the lock or clear it (depending on \var{l\_type} in the +\var{flock} structure). if the lock is held by another process, an error +occurs. +\item[F\_GetLkw] Same as for \textbf{F\_Setlk}, but wait until the lock is +released. +\item[F\_SetOwn] Set the Process or process group that owns a socket. +\end{description} +} +{ +\var{LinuxError} is used to report errors. +\begin{description} +\item[sys\_ebadf] \var{Fd} has a bad file descriptor. +\item[sys\_eagain or sys\_eaccess] For \textbf{F\_SetLk}, if the lock is +held by another process. +\end{description} +} +{\seef{Fcntl}, \seem{Fcntl}{2} } + +\procedure{Dup}{(Var OldFile, NewFile : Text)} +{ +Makes \var{NewFile} an exact copy of \var{OldFile}, after having flushed the +buffer of \var{OldFile}. Due to the buffering mechanism of Pascal, this has not +the same functionality as the \seem{dup}{2} call in C. The internal Pascal +buffers are not the same after this call, but when the buffers are flushed +(e.g. after output), the output is sent to the same file. +Doing an lseek will, however, work as in C, i.e. doing a lseek will change the +fileposition in both files. +} +{ \var{Linuxerror} is used to report errors. +\begin{description} +\item[sys\_ebadf] \var{OldFile} hasn't been assigned. +\item[sys\_emfile] Maximum number of open files for the process is reached. +\end{description} +} +{\seep{Dup2}, \seem{Dup}{2} } + +\input{linuxex/ex31.tex} + +\procedure{Dup2}{(Var OldFile, NewFile : Text)} +{ +Makes \var{NewFile} an exact copy of \var{OldFile}, after having flushed the +buffer of \var{OldFile}. \var{NewFile} can be an assigned file. +If \var{newfile} was open, it is closed first. +Due to the buffering mechanism of Pascal, this has not +the same functionality as the \seem{dup2}{2} call in C. The internal Pascal +buffers are not the same after this call, but when the buffers are flushed +(e.g. after output), the output is sent to the same file. +Doing an lseek will, however, work as in C, i.e. doing a lseek will change the +fileposition in both files. +} +{ \var{Linuxerror} is used to report errors. +\begin{description} +\item[sys\_ebadf] \var{OldFile} hasn't been assigned. +\item[sys\_emfile] Maximum number of open files for the process is reached. +\end{description} +} +{ \seep{Dup}, \seem{Dup2}{2} } + +\input{linuxex/ex32.tex} + +\procedure{SigAction}{(Signum : Integer; Var Act,OldAct : PSigActionRec)} +{ Changes the action to take upon receipt of a signal. \var{Act} and +\var{Oldact} are pointers to a \var{SigActionRec} record. + +\var{SigNum} specifies the signal, and can be any signal except +\textbf{SIGKILL} or \textbf{SIGSTOP}. + +If \var{Act} is non-nil, then the new action for signal \var{SigNum} is taken +from it. If \var{OldAct} is non-nil, the old action is stored there. + +\var{Sa\_Handler} may be \var{SIG\_DFL} for the default action or +\var{SIG\_IGN} to ignore the signal. + +\var{Sa\_Mask} Specifies which signals should be ignord during the execution +of the signal handler. + +\var{Sa\_Flags} Speciefies a series of flags which modify the behaviour of +the signal handler. You can 'or' none or more of the following : +\begin{description} +\item[SA\_NOCLDSTOP] If signum is \textbf{SIGCHLD} do not receive +notification when child processes stop. +\item[SA\_ONESHOT or SA\_RESETHAND] Restore the signal action to the default +state once the signal handler has been called. +\item[SA\_RESTART] For compatibility with BSD signals. +\item[SA\_NOMASK or SA\_NODEFER] Do not prevent the signal from being received +from within its own signal handler. +\end{description} +} +{\var{LinuxError} is used to report errors. +\begin{description} +\item[sys\_einval] an invalid signal was specified, or it was +\textbf{SIGKILL} or \textbf{SIGSTOP}. +\item[sys\_efault] \var{Act,OldAct} point outside this process address space +\item[sys\_eintr] System call was interrupted. +\end{description} +} +{ +\seep{SigProcMask}, \seef{SigPending}, \seep{SigSuspend}, \seef{Kill}, +\seem{Sigaction}{2} +} + +\procedure {SigProcMask}{(How : Integer; SSet,OldSSet : PSigSet)} +{ +Changes the list of currently blocked signals. The behaviour of the call +depends on \var{How} : +\begin{description} +\item[SIG\_BLOCK] The set of blocked signals is the union of the current set +and the \var{SSet} argument. +\item[SIG\_UNBLOCK] The signals in \var{SSet} are removed from the set of +currently blocked signals. +\item[SIG\_SETMASK] The list of blocked signals is set so \var{SSet}. +\end{description} +If \var{OldSSet} is non-nil, then the old set is stored in it. +} +{\var{LinuxError} is used to report errors. +\begin{description} +\item[sys\_efault] \var{SSet} or \var{OldSSet} point to an adress outside +the range of the process. +\item[sys\_eintr] System call was interrupted. +\end{description} +} +{\seep{SigAction}, \seef{SigPending}, \seep{SigSuspend}, \seef{Kill}, +\seem{Sigprocmask}{2} } + +\function{SigPending}{}{SigSet} +{ +Sigpending allows the examination of pending signals (which have been raised +while blocked.) The signal mask of pending signals is returned. +} +{None} +{\seep{SigAction}, \seep{SigProcMask}, \seep{SigSuspend}, \seef{Signal}, +\seef{Kill}, \seem{Sigpending}{2} } + +\procedure{SigSuspend}{(Mask : SigSet)} +{SigSuspend temporarily replaces the signal mask for the process with the one +given in \var{Mask}, and then suspends the process until a signal is received. +} +{None} +{\seep{SigAction}, \seep{SigProcMask}, \seef{SigPending}, \seef{Signal}, +\seef{Kill}, \seem{SigSuspend}{2} } + +\function{Signal}{(SigNum : Integer; Handler : PSignalHandler)}{PSignalHandler} +{ +Signal installs a new signal handler for signal \var{SigNum}. This call has +the same functionality as the \textbf{SigAction} call. + +The return value for Signal is the old signal handler, or nil on error. +} +{\var {LinuxError} is used to report errors : +\begin{description} +\item[SIG\_ERR] An error occurred. +\end{description} +} +{\seep{SigAction},\seef{Kill}, \seem{Signal}{2} } + +\function{Kill}{Pid : Longint; Sig : Integer)}{Integer} +{ Send a signal \var{Sig} to a process or process group. If \var{Pid}>0 then +the signal is sent to \var{Pid}, if it equals -1, then the signal is sent to +all processes except process 1. If \var{Pid}<-1 then the signal is sent to +process group -Pid. + +The return value is zero, except in case three, where the return value is the +number of processes to which the signal was sent. +} +{\var{LinuxError} is used to report errors: +\begin{description} +\item[sys\_einval] An invalid signal is sent. +\item[sys\_esrch] The \var{Pid} or process group don't exist. +\item[sys\_eperm] The effective userid of the current process doesn't math +the one of process \var{Pid}. +\end{description} +} +{\seep{SigAction}, \seef{Signal}, \seem{Kill}{2} } + +\function{GetHostName}{}{String} +{ +Get the hostname of the machine on which the process is running. +An empty string is returned if hostname is not set. +} +{None.} +{ \seef{GetDomainName},seem{Gethostname}{2} } + +\input{linuxex/ex40.tex} + +\function{GetDomainName}{}{String} +{ +Get the domain name of the machine on which the process is running. +An empty string is returned if the domain is not set. +} +{None.} +{ \seef{GetHostName},seem{Getdomainname}{2} } + +\input{linuxex/ex39.tex} + +\function{GetEnv}{(P : String)}{PChar} +{Returns the value of the environment variable in \var{P}. If the variable is +not defined, nil is returned. The value of the environment variable may be +the empty string. + +A PChar is returned to accomodate for strings longer than 255 bytes, +\var{TERMCAP} and \var{LS\_COLORS}, for instance. +} +{None.} +{\seem{sh}{1}, \seem{csh}{1} } + +\input{linuxex/ex41.tex} + +\function{Select}{(N : Longint; \\ var readfds,writefds,exceptfds : PFDset; +Var Timeout)}{Longint} +{\var{Select} checks one of the file descriptors in the \var{FDSets} to see if its +status changed. + +\var{readfds, writefds} and \var{exceptfds} are pointers to arrays of 256 +bits. If you want a file descriptor to be checked, you set the +corresponding element in the array to 1. The other elements in the array +must be set to zero. Three arrays are passed : The entries in \var{readfds} +are checked to see if characters become available for reading. The entries +in \var{writefds} are checked to see if it is OK to write to them, while +entries in \var{exceptfds} are cheked to see if an exception occorred on +them. + +You can use the functions \seepl{FD\_Clear}{FDClear}, \seepl{FD\_Clr}{FDClr}, +\seepl{FD\_Set}{FDSet}, \seefl{FD\_IsSet}{FDIsSet} to manipulate the individual elements of a set. + +The pointers can be nil. + +\var{N} is the largest index of a nonzero entry plus 1. (= the largest +file-descriptor + 1). + +\var{TimeOut} can be used to set a time limit. +If \var{TimeOut} can be two types : +\begin{enumerate} +\item \var{TimeOut} is of type \var{PTime} and contains a +zero time, the call returns immediately. If \var{TimeOut} is \var{Nil}, the +kernel will wait forever, or until a status changed. +\item \var{TimeOut} is of type \var{Longint}. If it is -1, this has the same +effect as a \var{Timeout} of type \var{PTime} which is \var{Nil}. +Otherwise, \var{TimeOut} contains a time in milliseconds. +\end{enumerate} + +When the TimeOut is reached, or one of the file descriptors has changed, +the \var{Select} call returns. On return, it will have modified the entries +in the array which have actually changed, and it returns the number of +entries that have been changed. If the timout was reached, and no decsriptor +changed, zero is returned; The arrays of indexes are undefined after that. +On error, -1 is returned.} +{On error, the function returns -1, and Errors are reported in LinuxError : +\begin{description} +\item[SYS\_EBADF\ ] An invalid descriptot was specified in one of the sets. +\item[SYS\_EINTR\ ] A non blocked signal was caught. +\item[SYS\_EINVAL\ ] \var{N} is negative or too big. +\item[SYS\_ENOMEM\ ] \var{Select} was unable to allocate memory for its + internal tables. +\end{description}} +{\seef{SelectText}, \seef{GetFS}, +\seepl{FD\_Clear}{FDClear}, +\seepl{FD\_Clr}{FDClr}, +\seepl{FD\_Set}{FDSet}, +\seefl{FD\_IsSet}{FDIsSet}} + +\input{linuxex/ex33.tex} + +\function{SelectText}{( var T : Text; TimeOut :PTime)}{Longint} +{\var{SelectText} executes the \seef{Select} call on a file of type +\var{Text}. You can specify a timeout in \var{TimeOut}. The SelectText call +determines itself whether it should check for read or write, depending on +how the file was opened : With \var{Reset} it is checked for reading, with +\var{Rewrite} and \var{Append} it is checked for writing.} +{See \seef{Select}. \var{SYS\_EBADF} can also mean that the file wasn't +opened.} +{\seef{Select}, \seef{GetFS}} +\function{GetFS}{(Var F : Any File Type)}{Longint} +{\var{GetFS} returns the file selector that the kernel provided for your +file. In principle you don' need this file selector. Only for some calls +it is needed, such as the \seef{Select} call or so.} +{In case the file was not opened, then -1 is returned.} +{\seef{Select}} + +\input{linuxex/ex34.tex} + +\procedurel{FD\_Clear}{FDClear}{(var fds:fdSet)} +{\var{FD\_Clear} clears all the filedescriptors in the file descriptor +set \var{fds}.} +{None.} +{\seef{Select}, +\seef{SelectText}, +\seef{GetFS}, +\seepl{FD\_Clr}{FDClr}, +\seepl{FD\_Set}{FDSet}, +\seefl{FD\_IsSet}{FDIsSet} + +} + +For an example, see \seef{Select}. + +\procedurel{FD\_Clr}{FDClr}{(fd:longint;var fds:fdSet)} +{ \var{FD\_Clr} clears file descriptor \var{fd} in filedescriptor s + et \var{fds}.} +{None.} +{\seef{Select}, +\seef{SelectText}, +\seef{GetFS}, +\seepl{FD\_Clear}{FDClear}, +\seepl{FD\_Set}{FDSet}, +\seefl{FD\_IsSet}{FDIsSet}} + +For an example, see \seef{Select}. + +\procedurel{FD\_Set}{FDSet}{(fd:longint;var fds:fdSet)} +{\var{FD\_Set} sets file descriptor \var{fd} in filedescriptor set \var{fds}.} +{None.} +{\seef{Select}, \seef{SelectText}, \seef{GetFS},\seepl{FD\_Clear}{FDClear}, +\seepl{FD\_Clr}{FDClr}, \seefl{FD\_IsSet}{FDIsSet}} + +For an example, see \seef{Select}. + +\functionl{FD\_IsSet}{FDIsSet}{(fd:longint;var fds:fdSet)}{boolean} +{\var{FD\_Set} Checks whether file descriptor \var{fd} in filedescriptor set \var{fds} +is set.} +{None.} +{\seef{Select}, \seef{SelectText}, \seef{GetFS}, +\seepl{FD\_Clear}{FDClear}, +\seepl{FD\_Clr}{FDClr}, +\seepl{FD\_Set}{FDSet}} + +For an example, see \seef{Select}. + +\function{fdOpen}{(pathname:string;flags:longint[; Mode: longint])}{longint} +{ \var{fdOpen} opens a file in \var{pathname} with flags \var{flags} a ORed combination of + \var{Open\_Accmode, Open\_RdOnly, Open\_WrOnly, Open\_RdWr, Open\_Creat, + Open\_Excl, Open\_NoCtty, Open\_Trunc, Open\_Append, Open\_NonBlock, + Open\_NDelay, Open\_Sync} + + The optional \var{mode} argument specifies the permissions to set when opening + the file. This is modified by the umask setting. The real permissions are + \var{Mode and not umask}. + + The return value of the function is the filedescriptor, or a negative + value if there was an error. +} +{Errors are returned in LinuxError} +{\seef{fdClose}, \seef{fdRead}, \seef{fdWrite},\seef{fdTruncate}} + +\input{linuxex/ex19.tex} + +\function{fdClose}{(fd:longint)}{boolean} +{ +\var{fdClose} closes a file with file descriptor \var{Fd}. The function +returns \var{True} if the file was closed successfully, \var{False} +otherwise. +} +{Errors are returned in LinuxError} +{\seef{fdOpen}, \seef{fdRead}, \seef{fdWrite},\seef{fdTruncate}} + +For an example, see \seef{fdOpen}. + +\function{fdRead}{(fd:longint;var buf;size:longint}{longint} +{ \var{fdRead} reads at most \var{size} bytes from the file descriptor +\var{fd}, and stores them in \var{buf}. + +The function returns the number of bytes actually read, or -1 if +an error occurred. + +No checking on the length of \var{buf} is done. +} +{Errors are returned in LinuxError.} +{\seef{fdOpen}, \seef{fdClose}, \seef{fdWrite},\seef{fdTruncate}} + +\input{linuxex/ex20.tex} + +\function{fdWrite}{(fd:longint;var buf;size:longint}{longint} +{\var{fdWrite} writes at most \var{size} bytes from \var{buf} to +file descriptor \var{fd}. + +The function returns the number of bytes actually written, or -1 if an error +occurred. +} +{Errors are returned in LinuxError.} +{\seef{fdOpen}, \seef{fdClose}, \seef{fdRead},\seef{fdTruncate}} + +For an example, see \seef{fdOpen}. + +\function{fdTruncate}{(fd,size:longint}{boolean} +{\var{fdTruncate} sets the length of a file in \var{fd} on \var{size} +bytes, where \var{size} must be less than or equal to the current length of +the file in \var{fd}. + +The function returns \var{True} if the call was successful, \var{false} if +an error occurred.} +{Errors are returned in LinuxError.} +{\seef{fdOpen}, \seef{fdClose}, \seef{fdRead},\seef{fdWrite}} + +For an example, see \seef{fdRead}. + +\functionl{S\_ISLNK}{ISLNK}{(m:integer)}{boolean} +{ \var{S\_ISLNK} checks the file mode \var{m} to see whether the file is a +symbolic link. If so it returns \var{True} +} +{\seef{FStat}, + \seefl{S\_ISREG}{ISREG}, + \seefl{S\_ISDIR}{ISDIR}, + \seefl{S\_ISCHR}{ISCHR}, + \seefl{S\_ISBLK}{ISBLK}, + \seefl{S\_ISFIFO}{ISFIFO}, + \seefl{S\_ISSOCK}{ISSOCK} +} + +\input{linuxex/ex53.tex} + +\functionl{S\_ISREG}{ISREG}{(m:integer)}{boolean} +{ \var{S\_ISREG} checks the file mode \var{m} to see whether the file is a +regular file. If so it returns \var{True} +} +{\seef{FStat}, + \seefl{S\_ISLNK}{ISLNK}, + \seefl{S\_ISDIR}{ISDIR}, + \seefl{S\_ISCHR}{ISCHR}, + \seefl{S\_ISBLK}{ISBLK}, + \seefl{S\_ISFIFO}{ISFIFO}, + \seefl{S\_ISSOCK}{ISSOCK} +} + +For an example, see \seef{ISLNK}. + +\functionl{S\_ISDIR}{ISDIR}{(m:integer)}{boolean} +{ \var{S\_ISDIR} checks the file mode \var{m} to see whether the file is a +directory. If so it returns \var{True} +} +{\seef{FStat}, + \seefl{S\_ISLNK}{ISLNK}, + \seefl{S\_ISREG}{ISREG}, + \seefl{S\_ISCHR}{ISCHR}, + \seefl{S\_ISBLK}{ISBLK}, + \seefl{S\_ISFIFO}{ISFIFO}, + \seefl{S\_ISSOCK}{ISSOCK} +} + +For an example, see \seef{ISLNK}. + +\functionl{S\_ISCHR}{ISCHR}{(m:integer)}{boolean} +{ \var{S\_ISCHR} checks the file mode \var{m} to see whether the file is a +character device file. If so it returns \var{True}. +} +{\seef{FStat}, + \seefl{S\_ISLNK}{ISLNK}, + \seefl{S\_ISREG}{ISREG}, + \seefl{S\_ISDIR}{ISDIR}, + \seefl{S\_ISBLK}{ISBLK}, + \seefl{S\_ISFIFO}{ISFIFO}, + \seefl{S\_ISSOCK}{ISSOCK} +} + +For an example, see \seef{ISLNK}. + +\functionl{S\_ISBLK}{ISBLK}{(m:integer)}{boolean} +{ \var{S\_ISBLK} checks the file mode \var{m} to see whether the file is a +block device file. If so it returns \var{True}. +} +{\seef{FStat}, + \seefl{S\_ISLNK}{ISLNK}, + \seefl{S\_ISREG}{ISREG}, + \seefl{S\_ISDIR}{ISDIR}, + \seefl{S\_ISCHR}{ISCHR}, + \seefl{S\_ISFIFO}{ISFIFO}, + \seefl{S\_ISSOCK}{ISSOCK} +} + +For an example, see \seef{ISLNK}. + +\functionl{S\_ISFIFO}{ISFIFO}{(m:integer)}{boolean} +{ \var{S\_ISFIFO} checks the file mode \var{m} to see whether the file is a +fifo (a named pipe). If so it returns \var{True}. +} +{\seef{FStat}, + \seefl{S\_ISLNK}{ISLNK}, + \seefl{S\_ISREG}{ISREG}, + \seefl{S\_ISDIR}{ISDIR}, + \seefl{S\_ISCHR}{ISCHR}, + \seefl{S\_ISBLK}{ISBLK}, + \seefl{S\_ISSOCK}{ISSOCK} +} + +For an example, see \seef{ISLNK}. + +\functionl{S\_ISSOCK}{ISSOCK}{(m:integer)}{boolean} +{ \var{S\_ISSOCK} checks the file mode \var{m} to see whether the file is a +socket. If so it returns \var{True}. +} +{\seef{FStat}, + \seefl{S\_ISLNK}{ISLNK}, + \seefl{S\_ISREG}{ISREG}, + \seefl{S\_ISDIR}{ISDIR}, + \seefl{S\_ISCHR}{ISCHR}, + \seefl{S\_ISBLK}{ISBLK}, + \seefl{S\_ISFIFO}{ISFIFO} +} + + +For an example, see \seef{ISLNK}. + +\function{OpenDir}{(f:pchar)}{pdir} +{ \var{OpenDir} opens the directory \var{f}, and returns a \var{pdir} +pointer to a \var{Dir} record, which can be used to read the directory +structure. If the directory cannot be opened, \var{nil} is returned.} +{Errors are returned in LinuxError.} +{\seef{CloseDir}, \seef{ReadDir}, \seep{SeekDir}, \seef{TellDir}, +\seem{opendir}{3}} + +\input{linuxex/ex35.tex} + +\function{CloseDir}{(p:pdir)}{integer} +{ \var{CloseDir} closes the directory pointed to by \var{p}. +It returns zero if the directory was closed succesfully, -1 otherwise.} +{Errors are returned in LinuxError.} +{\seef{OpenDir}, \seef{ReadDir}, \seep{SeekDir}, \seef{TellDir}, +\seem{closedir}{3}} + +For an example, see \seef{OpenDir}. + +\function{ReadDir}{(p:pdir)}{pdirent} +{\var{ReadDir} reads the next entry in the directory pointed to by \var{p}. +It returns a \var{pdirent} pointer to a structure describing the entry. +If the next entry can't be read, \var{Nil} is returned. +} +{Errors are returned in LinuxError.} +{\seef{CloseDir}, \seef{OpenDir}, \seep{SeekDir}, \seef{TellDir}, +\seem{readdir}{3}} + +For an example, see \seef{OpenDir}. + +\procedure {SeekDir}{(p:pdir;off:longint)} +{ \var{SeekDir} sets the directory pointer to the \var{off}-th entry in the +directory structure pointed to by \var{p}.} +{Errors are returned in LinuxError.} +{\seef{CloseDir}, \seef{ReadDir}, \seef{OpenDir}, \seef{TellDir}, +\seem{seekdir}{3}} + +For an example, see \seef{OpenDir}. + +\function{TellDir}{(p:pdir)}{longint} +{ \var{TellDir} returns the current location in the directory structure +pointed to by \var{p}. It returns -1 on failure.} +{Errors are returned in LinuxError.} +{\seef{CloseDir}, \seef{ReadDir}, \seep{SeekDir}, \seef{OpenDir}, +\seem{telldir}{3}} + +For an example, see \seef{OpenDir}. + +\procedure{Uname}{(var unamerec:utsname)} +{\var{Uname} gets the name and configuration of the current \linux kernel, +and returns it in \var{unamerec}. +} +{\var{LinuxError} is used to report errors.} +{\seef{GetHostName}, \seef{GetDomainName}, \seem{uname}{2}} + +\function{WaitPid}{(Pid : longint; Status : pointer; Options : Integer)}{Longint} +{ \var{WaitPid} waits for a child process with process ID \var{Pid} to exit. The +value of \var{Pid} can be one of the following: +\begin{description} +\item[Pid < -1] Causes \var{WaitPid} to wait for any child process whose + process group ID equals the absolute value of \var{pid}. + +\item[Pid = -1] Causes \var{WaitPid} to wait for any child process. + +\item[Pid = 0] Causes \var{WaitPid} to wait for any child process whose + process group ID equals the one of the calling + process. + +\item[Pid > 0] Causes \var{WaitPid} to wait for the child whose process ID +equals the value of \var{Pid}. +\end{description} +The \var{Options} parameter can be used to specify further how \var{WaitPid} +behaves: +\begin{description} +\item [WNOHANG] Causes \var{Waitpid} to return immediately if no child has +exited. +\item [WUNTRACED] Causes \var{WaitPid} to return also for children which are +stopped, but whose status has not yet been reported. +\end{description} + +Upon return, it returns the exit status of the process, or -1 in case of +failure. +} +{Errors are returned in LinuxError.} +{\seef{Fork}, \seep{Execve}, \seem{waitpid}{2}} + +for an example, see \seef{Fork}. + +\function{TCGetAttr}{(fd:longint;var tios:TermIOS)}{Boolean} +{ \var{TCGetAttr} + gets the terminal parameters from the terminal referred to by the file + descriptor \var{fd} and returns them in a \var{TermIOS} structure \var{tios}. + +The function returns \var{True} if the call was succesfull, \var{False} +otherwise. +} +{Errors are reported in LinuxError} +{\seef{TCSetAttr}, \seem{termios}{2} } + +\input{linuxex/ex55.tex} + +\function{TCSetAttr}{(Fd:longint;OptAct:longint;var Tios:TermIOS)}{Boolean} +{ \var{TCSetAttr} + Sets the terminal parameters you specify in a \var{TermIOS} structure +\var{Tios} for the terminal + referred to by the file descriptor \var{Fd}. \var{OptAct} specifies an + optional action when the set need to be done, + this could be one of the following pre-defined values: + \begin{description} +\item [TCSANOW\ ] set immediately. +\item [TCSADRAIN\ ] wait for output. +\item [TCSAFLUSH\ ] wait for output and discard all input not yet read. +\end{description} +The function Returns \var{True} if the call was succesfull, \var{False} +otherwise. +} +{Errors are reported in LinuxError.} +{\seef{TCGetAttr}, \seem{termios}{2}} + +For an example, see \seef{TCGetAttr}. + +\procedure{CFSetISpeed}{(var Tios:TermIOS;Speed:Longint)} +{ \var{CFSetISpeed} + Sets the input baudrate in the \var{TermIOS} structure \var{Tios} to + \var{Speed}. +} +{None.} +{\seep{CFSetOSpeed}, \seep{CFMakeRaw}, \seem{termios}{2}} + +\procedure{CFSetOSpeed}{(var Tios:TermIOS;Speed:Longint)} +{ \var{CFSetOSpeed} + Sets the output baudrate in the \var{Termios} structure \var{Tios} to + \var{Speed}. +} +{None.} +{\seep{CFSetISpeed}, \seep{CFMakeRaw}, \seem{termios}{2}} + +\procedure{CFMakeRaw}{(var Tios:TermIOS)} +{ \var{CFMakeRaw} + Sets the flags in the \var{Termios} structure \var{Tios} to a state so that + the terminal will function in Raw Mode. +} +{None.} +{ \seep{CFSetOSpeed}, \seep{CFSetISpeed}, \seem{termios}{2}} + +For an example, see \seef{TCGetAttr}. + +\function{TCSendBreak}{(Fd,Duration:longint)}{Boolean} +{ \var{TCSendBreak} + Sends zero-valued bits on an asynchrone serial connection decsribed by + file-descriptor \var{Fd}, for duration \var{Duration}. + + The function returns \var{True} if the action was performed successfully, +\var{False} otherwise. +} +{Errors are reported in LinuxError.} +{\seem{termios}{2}} + +Function TCSetPGrp(Fd,Id:longint):boolean; +{ \var{TCSetPGrp} + Sets the Process Group Id to \var{Id}. + + The function returns \var{True} if the call was successful, \var{False} +otherwise. +} +{Errors are returned in LinuxError.} +{\seef{TCGetPGrp}\seem{termios}{2}} + +\function{TCGetPGrp}{(Fd:longint;var Id:longint)}{boolean} +{ \var{TCGetPGrp} + returns the process group ID of a foreground process group in \var{Id} + + The function returns \var{True} if the call was succesfull, \var{False} + otherwise +} +{Errors are reported in LinuxError} +{\seem{termios}{2}} + +\function{TCDrain}{(Fd:longint)}{Boolean} +{ \var{TCDrain} + waits until all data to file descriptor \var{Fd} is transmitted. + + The function returns \var{True} if the call was succesfull, \var{False} + otherwise. +} +{Errors are reported in LinuxError} +{\seem{termios}{2}} + +\function {TCFlow}{(Fd,Act:longint)}{Boolean} +{ \var{TCFlow} + suspends/resumes transmission or reception of data to or from the file +descriptor \var{Fd}, depending + on the action \var {Act}. This can be one of the following pre-defined +values: +\begin{description} +\item [TCOOFF\ ] suspend reception/transmission, +\item [TCOON\ ] resume reception/transmission, +\item [TCIOFF\ ] transmit a stop character to stop input from the terminal, +\item [TCION\ ] transmit start to resume input from the terminal. +\end{description} + +The function returns \var{True} if the call was succesfull, \var{False} +otherwise. +} +{Errors are reported in LinuxError.} +{\seem{termios}{2}} + +\function{TCFlush}{(Fd,QSel:longint)}{Boolean} +{ \var{TCFlush} + discards all data sent or received to/from file descriptor \var{fd}. + \var{QSel} indicates which queue + should be discard. It can be one of the following pre-defined values : +\begin{description} +\item [TCIFLUSH\ ] input, +\item [TCOFLUSH\ ] output, +\item [TCIOFLUSH\ ] both input and output. +\end{description} + +The function returns \var{True} if the call was succesfull, \var{False} +otherwise. +} +{Errors are reported in LinuxError.} +{\seem{termios}{2}} + diff --git a/docs/linuxex/Makefile b/docs/linuxex/Makefile new file mode 100644 index 0000000000..4ec4b14a83 --- /dev/null +++ b/docs/linuxex/Makefile @@ -0,0 +1,58 @@ +####################################################################### +# +# Makefile to compile all examples and convert them to LaTeX +# +####################################################################### + +# Compiler +PP=ppc386 + +# Unit directory +# UNITDIR=/usr/lib/ppc/0.99.0/linuxunits + + +# Any options you wish to pass. +PPOPTS= + +# Script to convert the programs to LaTeX examples which can be included. +PP2TEX=pp2tex + +# Script to collect all examples in 1 file. +MAKETEX=make1tex + +####################################################################### +# No need to edit after this line. +####################################################################### + +ifdef UNITDIR +PPOPTS:=$(PPOPTS) -Up$(UNITDIR); +endif + +.SUFFIXES: .pp .tex + +.PHONY: all tex clean + +OBJECTS=ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex11 ex12 ex13 ex14 \ + ex15 ex16 ex17 ex18 ex19 ex20 ex21 ex22 ex23 ex24 ex25 ex26 ex27 \ + ex28 ex29 ex30 ex31 ex32 ex33 ex34 ex35 ex36 ex37 ex38 ex39 ex40 \ + ex41 ex42 ex43 ex44 ex45 ex46 ex47 ex48 ex49 ex51 ex52 ex53 ex54 ex55 +# ex56 ex57 ex58 ex59 ex60 ex61 ex62 ex63 ex64 ex65 ex66 \ +# ex67 ex68 ex69 ex70 ex71 ex72 ex73 ex74 ex75 ex76 ex77 + +TEXOBJECTS=$(addsuffix .tex, $(OBJECTS)) + +all : $(OBJECTS) + +tex : $(TEXOBJECTS) + +onetex : tex + $(MAKETEX) $(TEXOBJECTS) + +clean : + rm -f *.o *.s $(OBJECTS) $(TEXOBJECTS) + +$(OBJECTS): %: %.pp + $(PP) $(PPOPTS) $* + +$(TEXOBJECTS): %.tex: %.pp head.tex foot.tex + $(PP2TEX) $* diff --git a/docs/linuxex/README b/docs/linuxex/README new file mode 100644 index 0000000000..65c481bff0 --- /dev/null +++ b/docs/linuxex/README @@ -0,0 +1,58 @@ +These are the example programs that appear in the FPC documentation. + +Units guide, Linux unit : + +ex1.pp contains an example of the GetEpochTime function. +ex2.pp contains an example of the GetTimeOfDay function. +ex3.pp contains an example of the EpochToLocal function. +ex4.pp contains an example of the LocalToEpoch function. +ex5.pp contains an example of the GetTime function. +ex6.pp contains an example of the GetDate function. +ex7.pp contains an example of the Execve function. +ex8.pp contains an example of the Execv function. +ex9.pp contains an example of the Execvp function. +ex10.pp contains an example of the Execl function. +ex11.pp contains an example of the Execle function. +ex11.pp contains an example of the Execlp function. +ex13.pp contains an example of the Shell function. +ex14.pp contains an example of the Fork function. +ex15.pp contains an example of the Nice, Set- and GetPriority functions. +ex16.pp contains an example of the GetPid and GetPPid functions. +ex17.pp contains an example of the GetUid and GetEUid functions. +ex18.pp contains an example of the GetGid and GetEgid functions. +ex19.pp contains an example of the fdOpen, fdWrite and fdCLose functions. +ex20.pp contains an example of the fdRead and fdTuncate functions. +ex21.pp contains an example of the Link and UnLink functions. +ex22.pp contains an example of the SymLink and UnLink functions. +ex23.pp contains an example of the Chmod function. +ex24.pp contains an example of the Chown function. +ex25.pp contains an example of the UTime function. +ex26.pp contains an example of the Access function. +ex27.pp contains an example of the Umask function. +ex28.pp contains an example of the FStat function. +ex29.pp contains an example of the LStat function. +ex30.pp contains an example of the FSStat function. +ex31.pp contains an example of the Dup function. +ex32.pp contains an example of the Dup2 function. +ex33.pp contains an example of the Select function. +ex34.pp contains an example of the SelectText function. +ex35.pp contains an example of the OpenDir, ReadDir Telldir and SeekDir functions. +ex36.pp contains an example of the AssignPipe function. +ex37.pp contains an example of the POpen and PClose functions. +ex38.pp contains an example of the AssignStream function. +ex39.pp contains an example of the GetDomainName function. +ex40.pp contains an example of the GetHostName function. +ex41.pp contains an example of the GetEnv function. +ex42.pp contains an example of the SysInfo function. +ex43.pp contains an example of the Uname function. +ex44.pp contains an example of the Octal function. +ex45.pp contains an example of the FExpand function. +ex46.pp contains an example of the FSearch function. +ex47.pp contains an example of the DirName function. +ex48.pp contains an example of the BaseName function. +ex49.pp contains an example of the Glob function. +ex51.pp contains an example of the StringToPPChar function. +ex52.pp contains an example of the GetFS function. +ex53.pp contains an example of the S_ISLNK and related functions. +ex54.pp contains an example of the IOCtl function. +ex55.pp contains an example of the TCGetAttr,TCSetAttr,CFMakeRaw functions. diff --git a/docs/linuxex/ex1.pp b/docs/linuxex/ex1.pp new file mode 100644 index 0000000000..945f182fcb --- /dev/null +++ b/docs/linuxex/ex1.pp @@ -0,0 +1,10 @@ +Program Example1; + +{ Program to demonstrate the GetEpochTime function. } + +Uses linux; + +begin + Write ('Secs past the start of the Epoch (00:00 1/1/1980) : '); + Writeln (GetEpochTime); +end. diff --git a/docs/linuxex/ex10.pp b/docs/linuxex/ex10.pp new file mode 100644 index 0000000000..6263769298 --- /dev/null +++ b/docs/linuxex/ex10.pp @@ -0,0 +1,11 @@ +Program Example10; + +{ Program to demonstrate the Execl function. } + +Uses linux, strings; + +begin + { Execute 'ls -l', with current environment. } + { 'ls' is NOT looked for in PATH environment variable.} + Execl ('/bin/ls -l'); +end. diff --git a/docs/linuxex/ex11.pp b/docs/linuxex/ex11.pp new file mode 100644 index 0000000000..5561bd56ac --- /dev/null +++ b/docs/linuxex/ex11.pp @@ -0,0 +1,12 @@ +Program Example11; + +{ Program to demonstrate the Execle function. } + +Uses linux, strings; + +begin + { Execute 'ls -l', with current environment. } + { 'ls' is NOT looked for in PATH environment variable.} + { envp is defined in the system unit.} + Execle ('/bin/ls -l',envp); +end. diff --git a/docs/linuxex/ex12.pp b/docs/linuxex/ex12.pp new file mode 100644 index 0000000000..c2b7f006ce --- /dev/null +++ b/docs/linuxex/ex12.pp @@ -0,0 +1,12 @@ +Program Example12; + +{ Program to demonstrate the Execlp function. } + +Uses linux, strings; + +begin + { Execute 'ls -l', with current environment. } + { 'ls' is looked for in PATH environment variable.} + { envp is defined in the system unit.} + Execlp ('ls -l',envp); +end. diff --git a/docs/linuxex/ex13.pp b/docs/linuxex/ex13.pp new file mode 100644 index 0000000000..dcfbc030b1 --- /dev/null +++ b/docs/linuxex/ex13.pp @@ -0,0 +1,11 @@ +Program Example13; + +{ Program to demonstrate the Shell function. } + +Uses linux; + +begin + { This will send the output of 'ls -l' to the file ls.out } + { thanks to the shell's redirection functionality } + Shell ('ls -l >ls.out') +end. diff --git a/docs/linuxex/ex14.pp b/docs/linuxex/ex14.pp new file mode 100644 index 0000000000..7a091adf6d --- /dev/null +++ b/docs/linuxex/ex14.pp @@ -0,0 +1,24 @@ +Program Example14; + +{ Program to demonstrate the Fork and WaitPidfunction. } + +Uses linux; + +Var PID, ExitStatus : Longint; + +begin + Writeln ('Spawning a child'); + PID:=Fork; + If PID=0 then + begin + Writeln ('Hello From the Child !!'); + Writeln ('Exiting with exit status 1 !'); + Halt (1); + end + Else + begin + Writeln ('Spawned child with PID : ',PID); + WaitPid (PID,@ExitStatus,0); + Writeln ('Child exited with status : ',ExitStatus shr 8); + end; +end. diff --git a/docs/linuxex/ex15.pp b/docs/linuxex/ex15.pp new file mode 100644 index 0000000000..d344821cff --- /dev/null +++ b/docs/linuxex/ex15.pp @@ -0,0 +1,14 @@ +Program Example15; + +{ Program to demonstrate the Nice and Get/SetPriority functions. } + +Uses linux; + +begin + writeln ('Setting priority to 5'); + setpriority (prio_process,getpid,5); + writeln ('New priority = ',getpriority (prio_process,getpid)); + writeln ('Doing nice 10'); + nice (10); + writeln ('New Priority = ',getpriority (prio_process,getpid)); +end. diff --git a/docs/linuxex/ex16.pp b/docs/linuxex/ex16.pp new file mode 100644 index 0000000000..b1517874b7 --- /dev/null +++ b/docs/linuxex/ex16.pp @@ -0,0 +1,9 @@ +Program Example16; + +{ Program to demonstrate the GetPid, GetPPid function. } + +Uses linux; + +begin + Writeln ('Process Id = ',getpid,' Parent process Id = ',getppid); +end. diff --git a/docs/linuxex/ex17.pp b/docs/linuxex/ex17.pp new file mode 100644 index 0000000000..c8518b018f --- /dev/null +++ b/docs/linuxex/ex17.pp @@ -0,0 +1,9 @@ +Program Example17; + +{ Program to demonstrate the GetUid and GetEUid functions. } + +Uses linux; + +begin + writeln ('User Id = ',getuid,' Effective user Id = ',geteuid); +end. diff --git a/docs/linuxex/ex18.pp b/docs/linuxex/ex18.pp new file mode 100644 index 0000000000..f3d1952e82 --- /dev/null +++ b/docs/linuxex/ex18.pp @@ -0,0 +1,9 @@ +Program Example18; + +{ Program to demonstrate the GetGid and GetEGid functions. } + +Uses linux; + +begin + writeln ('Group Id = ',getgid,' Effective group Id = ',getegid); +end. diff --git a/docs/linuxex/ex19.pp b/docs/linuxex/ex19.pp new file mode 100644 index 0000000000..db55a1c868 --- /dev/null +++ b/docs/linuxex/ex19.pp @@ -0,0 +1,19 @@ +Program Example19; + +{ Program to demonstrate the fdOpen, fdwrite and fdCLose functions. } + +Uses linux; + +Const Line : String[80] = 'This is easy writing !'; + +Var FD : Longint; + +begin + FD:=fdOpen ('Test.dat',Open_WrOnly or Open_Creat); + if FD>0 then + begin + if length(Line)<>fdwrite (FD,Line[1],Length(Line)) then + Writeln ('Error when writing to file !'); + fdClose(FD); + end; +end. diff --git a/docs/linuxex/ex2.pp b/docs/linuxex/ex2.pp new file mode 100644 index 0000000000..d4be8d2cbb --- /dev/null +++ b/docs/linuxex/ex2.pp @@ -0,0 +1,17 @@ +Program Example2; + +{ Program to demonstrate the GetTimeOfDay function. } + +Uses linux; + +Var TV : TimeVal; + TZ : TimeZone; + +begin + GetTimeOfDay (TV,TZ); + Writeln ('Seconds : ',tv.sec); + Writeln ('Milliseconds : ',tv.usec); + Writeln ('Minutes west of GMT : ',tz.minuteswest); + Writeln ('Daylight Saving Time : ',tz.dsttime); + Writeln ('Seconds in 1 call : ',GetTimeOfDay); +end. diff --git a/docs/linuxex/ex20.pp b/docs/linuxex/ex20.pp new file mode 100644 index 0000000000..c64db7861e --- /dev/null +++ b/docs/linuxex/ex20.pp @@ -0,0 +1,46 @@ +Program Example20; + +{ Program to demonstrate the fdRead and fdTruncate functions. } + +Uses linux; + +Const Data : string[10] = '12345687890'; + +Var FD : Longint; + l : longint; + +begin + FD:=fdOpen('test.dat',open_wronly or open_creat,octal(666)); + if fd>0 then + begin + { Fill file with data } + for l:=1 to 10 do + if fdWrite (FD,Data[1],10)<>10 then + begin + writeln ('Error when writing !'); + halt(1); + end; + fdClose(FD); + FD:=fdOpen('test.dat',open_rdonly); + { Read data again } + If FD>0 then + begin + For l:=1 to 5 do + if fdRead (FD,Data[1],10)<>10 then + begin + Writeln ('Error when Reading !'); + Halt(2); + end; + fdCLose(FD); + { Truncating file at 60 bytes } + { For truncating, file must be open or write } + FD:=fdOpen('test.dat',open_wronly,octal(666)); + if FD>0 then + begin + if not fdTruncate(FD,60) then + Writeln('Error when truncating !'); + fdClose (FD); + end; + end; + end; +end. diff --git a/docs/linuxex/ex21.pp b/docs/linuxex/ex21.pp new file mode 100644 index 0000000000..700798a614 --- /dev/null +++ b/docs/linuxex/ex21.pp @@ -0,0 +1,31 @@ +Program Example21; + +{ Program to demonstrate the Link and UnLink functions. } + +Uses linux; + +Var F : Text; + S : String; +begin + Assign (F,'test.txt'); + Rewrite (F); + Writeln (F,'This is written to test.txt'); + Close(f); + { new.txt and test.txt are now the same file } + if not Link ('test.txt','new.txt') then + writeln ('Error when linking !'); + { Removing test.txt still leaves new.txt } + If not Unlink ('test.txt') then + Writeln ('Error when unlinking !'); + Assign (f,'new.txt'); + Reset (F); + While not EOF(f) do + begin + Readln(F,S); + Writeln ('> ',s); + end; + Close (f); + { Remove new.txt also } + If not Unlink ('new.txt') then + Writeln ('Error when unlinking !'); +end. diff --git a/docs/linuxex/ex22.pp b/docs/linuxex/ex22.pp new file mode 100644 index 0000000000..0af180e68f --- /dev/null +++ b/docs/linuxex/ex22.pp @@ -0,0 +1,33 @@ +Program Example22; + +{ Program to demonstrate the SymLink and UnLink functions. } + +Uses linux; + +Var F : Text; + S : String; + +begin + Assign (F,'test.txt'); + Rewrite (F); + Writeln (F,'This is written to test.txt'); + Close(f); + { new.txt and test.txt are now the same file } + if not SymLink ('test.txt','new.txt') then + writeln ('Error when symlinking !'); + { Removing test.txt still leaves new.txt + Pointing now to a non-existent file ! } + If not Unlink ('test.txt') then + Writeln ('Error when unlinking !'); + Assign (f,'new.txt'); + { This should fail, since the symbolic link + points to a non-existent file! } + {$i-} + Reset (F); + {$i+} + If IOResult=0 then + Writeln ('This shouldn''t happen'); + { Now remove new.txt also } + If not Unlink ('new.txt') then + Writeln ('Error when unlinking !'); +end. diff --git a/docs/linuxex/ex23.pp b/docs/linuxex/ex23.pp new file mode 100644 index 0000000000..703d34df3f --- /dev/null +++ b/docs/linuxex/ex23.pp @@ -0,0 +1,21 @@ +Program Example23; + +{ Program to demonstrate the Chmod function. } + +Uses linux; + +Var F : Text; + +begin + { Create a file } + Assign (f,'testex21'); + Rewrite (F); + Writeln (f,'#!/bin/sh'); + Writeln (f,'echo Some text for this file'); + Close (F); + { Octal() makes the correct number from a + number that LOOKS octal } + Chmod ('testex21',octal (777)); + { File is now executable } + execl ('./testex21'); +end. diff --git a/docs/linuxex/ex24.pp b/docs/linuxex/ex24.pp new file mode 100644 index 0000000000..c36c1d9074 --- /dev/null +++ b/docs/linuxex/ex24.pp @@ -0,0 +1,28 @@ +Program Example24; + +{ Program to demonstrate the Chown function. } + +Uses linux; + +Var UID,GID : Longint; + F : Text; + +begin + + Writeln ('This will only work if you are root.'); + Write ('Enter a UID : ');readln(UID); + Write ('Enter a GID : ');readln(GID); + Assign (f,'test.txt'); + Rewrite (f); + Writeln (f,'The owner of this file should become : '); + Writeln (f,'UID : ',UID); + Writeln (f,'GID : ',GID); + Close (F); + if not Chown ('test.txt',UID,GID) then + if LinuxError=Sys_EPERM then + Writeln ('You are not root !') + else + Writeln ('Chmod failed with exit code : ',LinuxError) + else + Writeln ('Changed owner successfully !'); +end. diff --git a/docs/linuxex/ex25.pp b/docs/linuxex/ex25.pp new file mode 100644 index 0000000000..959d592344 --- /dev/null +++ b/docs/linuxex/ex25.pp @@ -0,0 +1,24 @@ +Program Example25; + +{ Program to demonstrate the UTime function. } + +Uses linux; + +Var utim : utimbuf; + year,month,day,hour,minute,second : Word; + +begin + { Set access and modification time of executable source } + GetTime (hour,minute,second); + GetDate (year,month,day); + utim.actime:=LocalToEpoch(year,month,day,hour,minute,second); + utim.modtime:=utim.actime; + if not Utime('ex25.pp',utim) then + writeln ('Call to UTime failed !') + else + begin + Write ('Set access and modification times to : '); + Write (Hour:2,':',minute:2,':',second,', '); + Writeln (Day:2,'/',month:2,'/',year:4); + end; +end. diff --git a/docs/linuxex/ex26.pp b/docs/linuxex/ex26.pp new file mode 100644 index 0000000000..971a299c2a --- /dev/null +++ b/docs/linuxex/ex26.pp @@ -0,0 +1,13 @@ +Program Example26; + +{ Program to demonstrate the Access function. } + +Uses linux; + +begin + if Access ('/etc/passwd',W_OK) then + begin + Writeln ('Better check your system.'); + Writeln ('I can write to the /etc/passwd file !'); + end; +end. diff --git a/docs/linuxex/ex27.pp b/docs/linuxex/ex27.pp new file mode 100644 index 0000000000..f7ca836aff --- /dev/null +++ b/docs/linuxex/ex27.pp @@ -0,0 +1,10 @@ +Program Example27; + +{ Program to demonstrate the Umask function. } + +Uses linux; + +begin + Writeln ('Old Umask was : ',Umask(Octal(111))); + WRiteln ('New Umask is : ',Octal(111)); +end. diff --git a/docs/linuxex/ex28.pp b/docs/linuxex/ex28.pp new file mode 100644 index 0000000000..5dbb73ad04 --- /dev/null +++ b/docs/linuxex/ex28.pp @@ -0,0 +1,39 @@ +program example28; + +{ Program to demonstrate the FStat function. } + +uses linux; + +var f : text; + i : byte; + info : stat; + +begin + { Make a file } + assign (f,'test.fil'); + rewrite (f); + for i:=1 to 10 do writeln (f,'Testline # ',i); + close (f); + { Do the call on made file. } + if not fstat ('test.fil',info) then + begin + writeln('Fstat failed. Errno : ',linuxerror); + halt (1); + end; + writeln; + writeln ('Result of fstat on file ''test.fil''.'); + writeln ('Inode : ',info.ino); + writeln ('Mode : ',info.mode); + writeln ('nlink : ',info.nlink); + writeln ('uid : ',info.uid); + writeln ('gid : ',info.gid); + writeln ('rdev : ',info.rdev); + writeln ('Size : ',info.size); + writeln ('Blksize : ',info.blksze); + writeln ('Blocks : ',info.blocks); + writeln ('atime : ',info.atime); + writeln ('mtime : ',info.mtime); + writeln ('ctime : ',info.ctime); + { Remove file } + erase (f); +end. \ No newline at end of file diff --git a/docs/linuxex/ex29.pp b/docs/linuxex/ex29.pp new file mode 100644 index 0000000000..afb24b2808 --- /dev/null +++ b/docs/linuxex/ex29.pp @@ -0,0 +1,63 @@ +program example29; + +{ Program to demonstrate the LStat function. } + +uses linux; + +var f : text; + i : byte; + info : stat; + +begin + { Make a file } + assign (f,'test.fil'); + rewrite (f); + for i:=1 to 10 do writeln (f,'Testline # ',i); + close (f); + { Do the call on made file. } + if not fstat ('test.fil',info) then + begin + writeln('Fstat failed. Errno : ',linuxerror); + halt (1); + end; + writeln; + writeln ('Result of fstat on file ''test.fil''.'); + writeln ('Inode : ',info.ino); + writeln ('Mode : ',info.mode); + writeln ('nlink : ',info.nlink); + writeln ('uid : ',info.uid); + writeln ('gid : ',info.gid); + writeln ('rdev : ',info.rdev); + writeln ('Size : ',info.size); + writeln ('Blksize : ',info.blksze); + writeln ('Blocks : ',info.blocks); + writeln ('atime : ',info.atime); + writeln ('mtime : ',info.mtime); + writeln ('ctime : ',info.ctime); + + If not SymLink ('test.fil','test.lnk') then + writeln ('Link failed !': linuxerror); + + if not lstat ('test.lnk',info) then + begin + writeln('LStat failed. Errno : ',linuxerror); + halt (1); + end; + writeln; + writeln ('Result of fstat on file ''test.lnk''.'); + writeln ('Inode : ',info.ino); + writeln ('Mode : ',info.mode); + writeln ('nlink : ',info.nlink); + writeln ('uid : ',info.uid); + writeln ('gid : ',info.gid); + writeln ('rdev : ',info.rdev); + writeln ('Size : ',info.size); + writeln ('Blksize : ',info.blksze); + writeln ('Blocks : ',info.blocks); + writeln ('atime : ',info.atime); + writeln ('mtime : ',info.mtime); + writeln ('ctime : ',info.ctime); + { Remove file and link } + erase (f); + unlink ('test.lnk'); +end. \ No newline at end of file diff --git a/docs/linuxex/ex3.pp b/docs/linuxex/ex3.pp new file mode 100644 index 0000000000..1da0c5b7e9 --- /dev/null +++ b/docs/linuxex/ex3.pp @@ -0,0 +1,13 @@ +Program Example3; + +{ Program to demonstrate the EpochToLocal function. } + +Uses linux; + +Var Year,month,day,hour,minute,seconds : Word; + +begin + EpochToLocal (GetEpochTime,Year,month,day,hour,minute,seconds); + Writeln ('Current date : ',Day:2,'/',Month:2,'/',Year:4); + Writeln ('Current time : ',Hour:2,':',minute:2,':',seconds:2); +end. diff --git a/docs/linuxex/ex30.pp b/docs/linuxex/ex30.pp new file mode 100644 index 0000000000..b0acc5031e --- /dev/null +++ b/docs/linuxex/ex30.pp @@ -0,0 +1,33 @@ +program Example30; + +{ Program to demonstrate the FSStat function. } + +uses linux; + +var s : string; + info : statfs; + +begin + writeln ('Info about current partition : '); + s:='.'; + while s<>'q' do + begin + if not fsstat (s,info) then + begin + writeln('Fstat failed. Errno : ',linuxerror); + halt (1); + end; + writeln; + writeln ('Result of fsstat on file ''',s,'''.'); + writeln ('fstype : ',info.fstype); + writeln ('bsize : ',info.bsize); + writeln ('bfree : ',info.bfree); + writeln ('bavail : ',info.bavail); + writeln ('files : ',info.files); + writeln ('ffree : ',info.ffree); + writeln ('fsid : ',info.fsid); + writeln ('Namelen : ',info.namelen); + write ('Type name of file to do fsstat. (q quits) :'); + readln (s) + end; +end. \ No newline at end of file diff --git a/docs/linuxex/ex31.pp b/docs/linuxex/ex31.pp new file mode 100644 index 0000000000..f6039b3462 --- /dev/null +++ b/docs/linuxex/ex31.pp @@ -0,0 +1,15 @@ +program Example31; + +{ Program to demonstrate the Dup function. } + +uses linux; + +var f : text; + +begin + if not dup (output,f) then + Writeln ('Dup Failed !'); + writeln ('This is written to stdout.'); + writeln (f,'This is written to the dup file, and flushed');flush(f); + writeln +end. \ No newline at end of file diff --git a/docs/linuxex/ex32.pp b/docs/linuxex/ex32.pp new file mode 100644 index 0000000000..268efeac28 --- /dev/null +++ b/docs/linuxex/ex32.pp @@ -0,0 +1,22 @@ +program Example31; + +{ Program to demonstrate the Dup function. } + +uses linux; + +var f : text; + i : longint; + +begin + Assign (f,'text.txt'); + Rewrite (F); + For i:=1 to 10 do writeln (F,'Line : ',i); + if not dup2 (output,f) then + Writeln ('Dup2 Failed !'); + writeln ('This is written to stdout.'); + writeln (f,'This is written to the dup file, and flushed'); + flush(f); + writeln; + { Remove file. Comment this if you want to check flushing.} + Unlink ('text.txt'); +end. \ No newline at end of file diff --git a/docs/linuxex/ex33.pp b/docs/linuxex/ex33.pp new file mode 100644 index 0000000000..4c9e3f9da4 --- /dev/null +++ b/docs/linuxex/ex33.pp @@ -0,0 +1,25 @@ +Program Example33; + +{ Program to demonstrate the Select function. } + +Uses linux; + +Var FDS : FDSet; + +begin + FD_Zero (FDS); + FD_Set (0,FDS); + Writeln ('Press the to continue the program.'); + { Wait until File descriptor 0 (=Input) changes } + Select (1,@FDS,nil,nil,nil); + { Get rid of in buffer } + readln; + Writeln ('Press key in less than 2 seconds...'); + FD_Zero (FDS); + FD_Set (0,FDS); + if Select (1,@FDS,nil,nil,2000)>0 then + Writeln ('Thank you !') + { FD_ISSET(0,FDS) would be true here. } + else + Writeln ('Too late !'); +end. diff --git a/docs/linuxex/ex34.pp b/docs/linuxex/ex34.pp new file mode 100644 index 0000000000..e904d77e9c --- /dev/null +++ b/docs/linuxex/ex34.pp @@ -0,0 +1,22 @@ +Program Example33; + +{ Program to demonstrate the SelectText function. } + +Uses linux; + +Var tv : TimeVal; + +begin + Writeln ('Press the to continue the program.'); + { Wait until File descriptor 0 (=Input) changes } + SelectText (Input,nil); + { Get rid of in buffer } + readln; + Writeln ('Press key in less than 2 seconds...'); + tv.sec:=2; + tv.usec:=0; + if SelectText (Input,@tv)>0 then + Writeln ('Thank you !') + else + Writeln ('Too late !'); +end. diff --git a/docs/linuxex/ex35.pp b/docs/linuxex/ex35.pp new file mode 100644 index 0000000000..18baca96e8 --- /dev/null +++ b/docs/linuxex/ex35.pp @@ -0,0 +1,46 @@ +Program Example35; + +{ Program to demonstrate the + OpenDir,ReadDir, SeekDir and TellDir functions. } + +Uses linux; + +Var TheDir : PDir; + ADirent : PDirent; + Entry : Longint; + +begin + TheDir:=OpenDir('./.'); + Repeat + Entry:=TellDir(TheDir); + ADirent:=ReadDir (TheDir); + If ADirent<>Nil then + With ADirent^ do + begin + Writeln ('Entry No : ',Entry); + Writeln ('Inode : ',ino); + Writeln ('Offset : ',off); + Writeln ('Reclen : ',reclen); + Writeln ('Name : ',pchar(@name[0])); + end; + Until ADirent=Nil; + Repeat + Write ('Entry No. you would like to see again (-1 to stop): '); + ReadLn (Entry); + If Entry<>-1 then + begin + SeekDir (TheDir,Entry); + ADirent:=ReadDir (TheDir); + If ADirent<>Nil then + With ADirent^ do + begin + Writeln ('Entry No : ',Entry); + Writeln ('Inode : ',ino); + Writeln ('Offset : ',off); + Writeln ('Reclen : ',reclen); + Writeln ('Name : ',pchar(@name[0])); + end; + end; + Until Entry=-1; + CloseDir (TheDir); +end. diff --git a/docs/linuxex/ex36.pp b/docs/linuxex/ex36.pp new file mode 100644 index 0000000000..326d0ea3d8 --- /dev/null +++ b/docs/linuxex/ex36.pp @@ -0,0 +1,28 @@ +Program Example36; + +{ Program to demonstrate the AssignPipe function. } + +Uses linux; + +Var pipi,pipo : Text; + s : String; + +begin + Writeln ('Assigning Pipes.'); + assignpipe(pipi,pipo); + if linuxerror<>0 then + Writeln('Error assigning pipes !'); + Writeln ('Rewrite Output pipe'); + rewrite (pipo); + Writeln ('Reset Input pipe '); + reset (pipi); + Writeln ('Writing to pipe, and flushing.'); + Writeln (pipo,'This is a textstring');flush(pipo); + Writeln ('Reading from pipe.'); + Readln (pipi,s); + Writeln ('Read from pipe : ',s); + close (pipo); + close (pipi); + writeln ('Closed pipes.'); + writeln +end. \ No newline at end of file diff --git a/docs/linuxex/ex37.pp b/docs/linuxex/ex37.pp new file mode 100644 index 0000000000..fe8a69c57e --- /dev/null +++ b/docs/linuxex/ex37.pp @@ -0,0 +1,33 @@ +Program Example37; + +{ Program to demonstrate the Popen function. } + +uses linux; + +var f : text; + i : longint; + +begin + writeln ('Creating a shell script to which echoes its arguments'); + writeln ('and input back to stdout'); + assign (f,'test21a'); + rewrite (f); + writeln (f,'#!/bin/sh'); + writeln (f,'echo this is the child speaking.... '); + writeln (f,'echo got arguments \*"$*"\*'); + writeln (f,'cat'); + writeln (f); + close (f); + chmod ('test21a',octal (755)); + popen (f,'./test21a arg1 arg2','W'); + if linuxerror<>0 then + writeln ('error from POpen : Linuxerror : ', Linuxerror); + for i:=1 to 10 do + writeln (f,'This is written to the pipe, and should appear on stdout.'); + closep (f); + writeln; + writeln ('Press to remove shell script.'); + readln; + assign (f,'test21a'); + erase (f) +end. \ No newline at end of file diff --git a/docs/linuxex/ex38.pp b/docs/linuxex/ex38.pp new file mode 100644 index 0000000000..70eec8139d --- /dev/null +++ b/docs/linuxex/ex38.pp @@ -0,0 +1,48 @@ +Program Example38; + +{ Program to demonstrate the AssignStream function. } + +Uses linux; + +Var Si,So : Text; + S : String; + i : longint; + +begin + if not (paramstr(1)='-son') then + begin + Writeln ('Calling son'); + Assignstream (Si,So,'./ex38a -son'); + if linuxerror<>0 then writeln ('AssignStream failed !'); +{$i-} +{ rewrite (so); + if ioresult<>0 then writeln ('Error !!'); + reset(si); + if ioresult<>0 then writeln ('Error !!'); + } Writeln ('Speaking to son'); + For i:=1 to 10 do writeln (so,'Hello son !'); + For i:=1 to 3 do writeln (so,'Hello chap !'); + flush (so); + while not eof(si) do + begin + readln (si,s); + writeln ('Father: Son said : ',S); + end; + Writeln ('Stopped conversation'); + Close (Si); + Close (so); + Writeln ('Put down phone'); + end + Else + begin + Writeln ('This is the son '); + While not eof (input) do + begin + readln (s); + if pos ('Hello son !',S)<>0 then + Writeln ('Hello Dad !') + else + writeln ('Who are you ?'); + end + end +end. diff --git a/docs/linuxex/ex39.pp b/docs/linuxex/ex39.pp new file mode 100644 index 0000000000..5017e48b1e --- /dev/null +++ b/docs/linuxex/ex39.pp @@ -0,0 +1,9 @@ +Program Example39; + +{ Program to demonstrate the GetDomainName function. } + +Uses linux; + +begin + Writeln ('Domain name of this machine is : ',GetDomainName); +end. diff --git a/docs/linuxex/ex4.pp b/docs/linuxex/ex4.pp new file mode 100644 index 0000000000..21e8b864df --- /dev/null +++ b/docs/linuxex/ex4.pp @@ -0,0 +1,19 @@ +Program Example4; + +{ Program to demonstrate the LocalToEpoch function. } + +Uses linux; + +Var year,month,day,hour,minute,second : Word; + +begin + Write ('Year : ');readln(Year); + Write ('Month : ');readln(Month); + Write ('Day : ');readln(Day); + Write ('Hour : ');readln(Hour); + Write ('Minute : ');readln(Minute); + Write ('Seonds : ');readln(Second); + Write ('This is : '); + Write (LocalToEpoch(year,month,day,hour,minute,second)); + Writeln (' seconds past 00:00 1/1/1980'); +end. diff --git a/docs/linuxex/ex40.pp b/docs/linuxex/ex40.pp new file mode 100644 index 0000000000..5d136a427a --- /dev/null +++ b/docs/linuxex/ex40.pp @@ -0,0 +1,9 @@ +Program Example40; + +{ Program to demonstrate the GetHostName function. } + +Uses linux; + +begin + Writeln ('Name of this machine is : ',GetHostName); +end. diff --git a/docs/linuxex/ex41.pp b/docs/linuxex/ex41.pp new file mode 100644 index 0000000000..2ea99743e8 --- /dev/null +++ b/docs/linuxex/ex41.pp @@ -0,0 +1,9 @@ +Program Example41; + +{ Program to demonstrate the GetEnv function. } + +Uses linux; + +begin + Writeln ('Path is : ',Getenv('PATH')); +end. diff --git a/docs/linuxex/ex42.pp b/docs/linuxex/ex42.pp new file mode 100644 index 0000000000..abfed218ee --- /dev/null +++ b/docs/linuxex/ex42.pp @@ -0,0 +1,22 @@ +Program Example42; + +{ Program to demonstrate the SysInfo function. } + +Uses linux; + +Var Info : TSysinfo; + +begin + If SysInfo (Info) then + With info do + begin + Writeln ('Uptime : ',uptime); + Writeln ('Load : ',loads[1],'/',Loads[2],'/',Loads[3]); + Writeln ('Total ram : ',TotalRam div 1024,'Kb.'); + Writeln ('Free ram : ',FreeRam div 1024,'Kb.'); + Writeln ('Shared ram : ',SharedRam div 1024,'Kb.'); + Writeln ('Total swap : ',Totalswap div 1024,'Kb.'); + Writeln ('Free swap : ',FreeSwap Div 1024,'Kb.'); + Writeln ('No. Processes : ',procs); + end; +end. diff --git a/docs/linuxex/ex43.pp b/docs/linuxex/ex43.pp new file mode 100644 index 0000000000..6c9cf4a686 --- /dev/null +++ b/docs/linuxex/ex43.pp @@ -0,0 +1,20 @@ +Program Example43; + +{ Program to demonstrate the Uname function. } + +Uses linux; + +Var UN : utsname; + +begin + if Uname (UN) then + With UN do + begin + Writeln ('Name : ',pchar(@sysname[0])); + Writeln ('Nodename : ',pchar(@Nodename[0])); + Writeln ('release : ',pchar(@Release[0])); + Writeln ('Version : ',pchar(@Version[0])); + Writeln ('Machine : ',pchar(@Machine[0])); + Writeln ('Domainname : ',pchar(@domainname[0])); + end; +end. diff --git a/docs/linuxex/ex44.pp b/docs/linuxex/ex44.pp new file mode 100644 index 0000000000..1c1e8a90ac --- /dev/null +++ b/docs/linuxex/ex44.pp @@ -0,0 +1,9 @@ +Program Example44; + +{ Program to demonstrate the Octal function. } + +Uses linux; + +begin + Writeln ('Octal(666) : ',octal(666)); +end. diff --git a/docs/linuxex/ex45.pp b/docs/linuxex/ex45.pp new file mode 100644 index 0000000000..67de7a3ba5 --- /dev/null +++ b/docs/linuxex/ex45.pp @@ -0,0 +1,9 @@ +Program Example45; + +{ Program to demonstrate the FExpand function. } + +Uses linux; + +begin + Writeln ('This program is in : ',FExpand(Paramstr(0))); +end. diff --git a/docs/linuxex/ex46.pp b/docs/linuxex/ex46.pp new file mode 100644 index 0000000000..610e9e304e --- /dev/null +++ b/docs/linuxex/ex46.pp @@ -0,0 +1,9 @@ +Program Example46; + +{ Program to demonstrate the FSearch function. } + +Uses linux,strings; + +begin + Writeln ('ls is in : ',FSearch ('ls',strpas(Getenv('PATH')))); +end. diff --git a/docs/linuxex/ex47.pp b/docs/linuxex/ex47.pp new file mode 100644 index 0000000000..c732b9b84c --- /dev/null +++ b/docs/linuxex/ex47.pp @@ -0,0 +1,12 @@ +Program Example47; + +{ Program to demonstrate the DirName function. } + +Uses linux; + +Var S : String; + +begin + S:=FExpand(Paramstr(0)); + Writeln ('This program is in directory : ',Dirname(S)); +end. diff --git a/docs/linuxex/ex48.pp b/docs/linuxex/ex48.pp new file mode 100644 index 0000000000..6ad2174089 --- /dev/null +++ b/docs/linuxex/ex48.pp @@ -0,0 +1,12 @@ +Program Example48; + +{ Program to demonstrate the BaseName function. } + +Uses linux; + +Var S : String; + +begin + S:=FExpand(Paramstr(0)); + Writeln ('This program is called : ',Basename(S,'')); +end. diff --git a/docs/linuxex/ex49.pp b/docs/linuxex/ex49.pp new file mode 100644 index 0000000000..fc39073829 --- /dev/null +++ b/docs/linuxex/ex49.pp @@ -0,0 +1,22 @@ +Program Example49; + +{ Program to demonstrate the Glob and GlobFree functions. } + +Uses linux; + +Var G1,G2 : PGlob; + +begin + G1:=Glob ('*'); + if LinuxError=0 then + begin + G2:=G1; + Writeln ('Files in this directory : '); + While g2<>Nil do + begin + Writeln (g2^.name); + g2:=g2^.next; + end; + GlobFree (g1); + end; +end. diff --git a/docs/linuxex/ex5.pp b/docs/linuxex/ex5.pp new file mode 100644 index 0000000000..909cffdb6a --- /dev/null +++ b/docs/linuxex/ex5.pp @@ -0,0 +1,12 @@ +Program Example5; + +{ Program to demonstrate the GetTime function. } + +Uses linux; + +Var Hour, Minute, Second : Word + +begin + GetTime (Hour, Minute, Second); + Writeln ('Time : ',Hour:2,':',Minute:2,':',Second:2); +end. diff --git a/docs/linuxex/ex51.pp b/docs/linuxex/ex51.pp new file mode 100644 index 0000000000..01dc352c9d --- /dev/null +++ b/docs/linuxex/ex51.pp @@ -0,0 +1,15 @@ +Program Example51; + +{ Program to demonstrate the StringToPPChar function. } + +Uses linux; + +var P : PPChar; + S : String; +begin + S:='/bin/ls -l -F'; + P:=StringToPPChar(S); + Writeln ('Name : ',p^); inc(longint(p),4); + writeln ('Option 1 : ',p^); inc(longint(p),4); + writeln ('Option 2 : ',p^); + end. diff --git a/docs/linuxex/ex52.pp b/docs/linuxex/ex52.pp new file mode 100644 index 0000000000..8229ad5b8a --- /dev/null +++ b/docs/linuxex/ex52.pp @@ -0,0 +1,11 @@ +Program Example52; + +{ Program to demonstrate the GetFS function. } + +Uses linux; + +begin + Writeln ('File descriptor of input ',getfs(input)); + Writeln ('File descriptor of output ',getfs(output)); + Writeln ('File descriptor of stderr ',getfs(stderr)); +end. diff --git a/docs/linuxex/ex53.pp b/docs/linuxex/ex53.pp new file mode 100644 index 0000000000..1ce06f55f6 --- /dev/null +++ b/docs/linuxex/ex53.pp @@ -0,0 +1,27 @@ +Program Example53; + +{ Program to demonstrate the S_ISLNK function. } + +Uses linux; + +Var Info : Stat; + +begin + if FStat (paramstr(1),info) then + begin + if S_ISLNK(info.mode) then + Writeln ('File is a link'); + if S_ISREG(info.mode) then + Writeln ('File is a regular file'); + if S_ISDIR(info.mode) then + Writeln ('File is a directory'); + if S_ISCHR(info.mode) then + Writeln ('File is a character device file'); + if S_ISBLK(info.mode) then + Writeln ('File is a block device file'); + if S_ISFIFO(info.mode) then + Writeln ('File is a named pipe (FIFO)'); + if S_ISSOCK(info.mode) then + Writeln ('File is a socket'); + end; +end. diff --git a/docs/linuxex/ex54.pp b/docs/linuxex/ex54.pp new file mode 100644 index 0000000000..a22333608d --- /dev/null +++ b/docs/linuxex/ex54.pp @@ -0,0 +1,15 @@ +Program Example1; + +uses Linux; + +{ Program to demonstrate the IOCtl function. } + +var + tios : Termios; +begin + IOCtl(1,TCGETS,@tios); + WriteLn('Input Flags : $',hexstr(tios.c_iflag,8)); + WriteLn('Output Flags : $',hexstr(tios.c_oflag,8)); + WriteLn('Line Flags : $',hexstr(tios.c_lflag,8)); + WriteLn('Control Flags: $',hexstr(tios.c_cflag,8)); +end. diff --git a/docs/linuxex/ex55.pp b/docs/linuxex/ex55.pp new file mode 100644 index 0000000000..2e2be19ed2 --- /dev/null +++ b/docs/linuxex/ex55.pp @@ -0,0 +1,30 @@ +Program Example1; + +uses Linux; + +{ Program to demonstrate the TCGetAttr/TCSetAttr/CFMakeRaw functions. } + +procedure ShowTermios(var tios:Termios); +begin + WriteLn('Input Flags : $',hexstr(tios.c_iflag,8)+#13); + WriteLn('Output Flags : $',hexstr(tios.c_oflag,8)); + WriteLn('Line Flags : $',hexstr(tios.c_lflag,8)); + WriteLn('Control Flags: $',hexstr(tios.c_cflag,8)); +end; + +var + oldios, + tios : Termios; +begin + WriteLn('Old attributes:'); + TCGetAttr(1,tios); + ShowTermios(tios); + oldios:=tios; + Writeln('Setting raw terminal mode'); + CFMakeRaw(tios); + TCSetAttr(1,TCSANOW,tios); + WriteLn('Current attributes:'); + TCGetAttr(1,tios); + ShowTermios(tios); + TCSetAttr(1,TCSANOW,oldios); +end. diff --git a/docs/linuxex/ex6.pp b/docs/linuxex/ex6.pp new file mode 100644 index 0000000000..06ca8e6b32 --- /dev/null +++ b/docs/linuxex/ex6.pp @@ -0,0 +1,12 @@ +Program Example6; + +{ Program to demonstrate the GetDate function. } + +Uses linux; + +Var Year, Month, Day : Word; + +begin + GetDate (Year, Month, Day); + Writeln ('Date : ',Day:2,'/',Month:2,'/',Year:4); +end. diff --git a/docs/linuxex/ex7.pp b/docs/linuxex/ex7.pp new file mode 100644 index 0000000000..ad94c547af --- /dev/null +++ b/docs/linuxex/ex7.pp @@ -0,0 +1,21 @@ +Program Example7; + +{ Program to demonstrate the Execve function. } + +Uses linux, strings; + +Const Arg0 : PChar = '/bin/ls'; + Arg1 : Pchar = '-l'; + +Var PP : PPchar; + + +begin + GetMem (PP,3*SizeOf(Pchar)); + PP[0]:=Arg0; + PP[1]:=Arg1; + PP[3]:=Nil; + { Execute '/bin/ls -l', with current environment } + { Envp is defined in system.inc } + ExecVe ('/bin/ls',pp,envp); +end. diff --git a/docs/linuxex/ex8.pp b/docs/linuxex/ex8.pp new file mode 100644 index 0000000000..c369b2cafc --- /dev/null +++ b/docs/linuxex/ex8.pp @@ -0,0 +1,20 @@ +Program Example8; + +{ Program to demonstrate the Execv function. } + +Uses linux, strings; + +Const Arg0 : PChar = '/bin/ls'; + Arg1 : Pchar = '-l'; + +Var PP : PPchar; + + +begin + GetMem (PP,3*SizeOf(Pchar)); + PP[0]:=Arg0; + PP[1]:=Arg1; + PP[3]:=Nil; + { Execute '/bin/ls -l', with current environment } + Execv ('/bin/ls',pp); +end. diff --git a/docs/linuxex/ex9.pp b/docs/linuxex/ex9.pp new file mode 100644 index 0000000000..10bdd83e21 --- /dev/null +++ b/docs/linuxex/ex9.pp @@ -0,0 +1,22 @@ +Program Example9; + +{ Program to demonstrate the Execvp function. } + +Uses linux, strings; + +Const Arg0 : PChar = 'ls'; + Arg1 : Pchar = '-l'; + +Var PP : PPchar; + + +begin + GetMem (PP,3*SizeOf(Pchar)); + PP[0]:=Arg0; + PP[1]:=Arg1; + PP[3]:=Nil; + { Execute 'ls -l', with current environment. } + { 'ls' is looked for in PATH environment variable.} + { Envp is defined in the system unit. } + Execvp ('ls',pp,envp); +end. diff --git a/docs/linuxex/foot.tex b/docs/linuxex/foot.tex new file mode 100644 index 0000000000..83788a402a --- /dev/null +++ b/docs/linuxex/foot.tex @@ -0,0 +1,2 @@ +\end{verbatim} +\end{FPKList} \ No newline at end of file diff --git a/docs/linuxex/head.tex b/docs/linuxex/head.tex new file mode 100644 index 0000000000..b2ed5b6603 --- /dev/null +++ b/docs/linuxex/head.tex @@ -0,0 +1,3 @@ +\begin{FPKList} +\item[Example] +\begin{verbatim} diff --git a/docs/linuxex/newex b/docs/linuxex/newex new file mode 100644 index 0000000000..45f07f89e7 --- /dev/null +++ b/docs/linuxex/newex @@ -0,0 +1,8 @@ +#!/bin/sh +if [ -e ex${1}.pp ]; then + mv ex${1}.pp ex${1}.pp.orig +fi +sed -e s/Example/Example$1/ -e s/\\\*\\\*\\\*/$2/ ex${1}.pp +echo "ex${1}.pp contains an example of the $2 function." >>README +joe ex${1}.pp +ppc386 ex${1}.pp && ex${1} diff --git a/docs/linuxex/pp2tex b/docs/linuxex/pp2tex new file mode 100644 index 0000000000..3a5cd6a448 --- /dev/null +++ b/docs/linuxex/pp2tex @@ -0,0 +1,5 @@ +#!/bin/sh +# Simply paste a header and footer to the program. +cat head.tex > $1.tex +cat $1.pp >> $1.tex +cat foot.tex >> $1.tex diff --git a/docs/linuxex/readme.dif b/docs/linuxex/readme.dif new file mode 100644 index 0000000000..4691407151 --- /dev/null +++ b/docs/linuxex/readme.dif @@ -0,0 +1,10 @@ +*** /root/cvs/docs/linuxex/README Sun Jan 11 23:24:10 1998 +--- README Fri Jan 16 17:46:39 1998 +*************** +*** 54,56 **** +--- 54,58 ---- + ex51.pp contains an example of the StringToPPChar function. + ex52.pp contains an example of the GetFS function. + ex53.pp contains an example of the S_ISLNK and related functions. ++ ex54.pp contains an example of the IOCtl function. ++ ex55.pp contains an example of the TCGetAttr,TCSetAttr,CFMakeRaw functions. diff --git a/docs/linuxex/template.pp b/docs/linuxex/template.pp new file mode 100644 index 0000000000..44d3db948f --- /dev/null +++ b/docs/linuxex/template.pp @@ -0,0 +1,8 @@ +Program Example; + +{ Program to demonstrate the *** function. } + +Uses linux; + +begin +end. diff --git a/docs/makehtm b/docs/makehtm new file mode 100644 index 0000000000..84dc75c6e7 --- /dev/null +++ b/docs/makehtm @@ -0,0 +1,8 @@ +#!/bin/sh +echo 'starting to convert. ' +for f in $* +do + sed s/\\.html/\\.htm/g <$f >`dirname $f`/`basename $f .html`.htm + echo -n '.' +done +echo 'Done.' diff --git a/docs/mmx.tex b/docs/mmx.tex new file mode 100644 index 0000000000..670b81d9fe --- /dev/null +++ b/docs/mmx.tex @@ -0,0 +1,93 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\chapter{The MMX unit} +This chapter describes the \file{MMX} unit. This unit allows you to use the +\var{MMX} capabilities of the \fpk compiler. It was written by Florian +Kl\"ampfl for the \var{I386} processor. +\section{Variables, Types and constants} +The following types are defined in the \var{MMX} unit: +\begin{verbatim} +tmmxshortint = array[0..7] of shortint; +tmmxbyte = array[0..7] of byte; +tmmxword = array[0..3] of word; +tmmxinteger = array[0..3] of integer; +tmmxfixed = array[0..3] of fixed16; +tmmxlongint = array[0..1] of longint; +tmmxcardinal = array[0..1] of cardinal; +{ for the AMD 3D } +tmmxsingle = array[0..1] of single; +\end{verbatim} +And the following pointers to the above types: +\begin{verbatim} +pmmxshortint = ^tmmxshortint; +pmmxbyte = ^tmmxbyte; +pmmxword = ^tmmxword; +pmmxinteger = ^tmmxinteger; +pmmxfixed = ^tmmxfixed; +pmmxlongint = ^tmmxlongint; +pmmxcardinal = ^tmmxcardinal; +{ for the AMD 3D } +pmmxsingle = ^tmmxsingle; +\end{verbatim} +The following initialized constants allow you to determine if the computer +has \var{MMX} extensions. They are set correctly in the unit's +initialization code. +\begin{verbatim} +is_mmx_cpu : boolean = false; +is_amd_3d_cpu : boolean = false; +\end{verbatim} + +\section{Functions and Procedures} + +\Procedure{Emms} +{\var{Emms} sets all floating point registers to empty. This procedure must +be called after you have used any \var{MMX} instructions, if you want to use +floating point arithmetic. If you just want to move floating point data +around, it isn't necessary to call this function, the compiler doesn't use +the FPU registers when moving data. Only when doing calculations, you should +use this function. +} +{None.} +{ \progref } +\begin{FPKList} +\item[Example:] +\begin{verbatim} +Program MMXDemo; + +uses mmx; + +var + d1 : double; + a : array[0..10000] of double; + i : longint; + +begin + d1:=1.0; +{$mmx+} + { floating point data is used, but we do _no_ arithmetic } + for i:=0 to 10000 do + a[i]:=d2; { this is done with 64 bit moves } +{$mmx-} + emms; { clear fpu } + { now we can do floating point arithmetic again } +end. +\end{verbatim} +\end{FPKList} \ No newline at end of file diff --git a/docs/onechap.tex b/docs/onechap.tex new file mode 100644 index 0000000000..53c8b835c6 --- /dev/null +++ b/docs/onechap.tex @@ -0,0 +1,38 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\documentclass{report} +\usepackage{a4} +\usepackage{makeidx} +\usepackage{html} +\latex{\usepackage{fpk}} +\html{\input{fpk-html.tex}} +\begin{document} +%\input{crt.tex} +%\input{dos.tex} +%\input{getopts.tex} +%\input{go32.tex} +%\input{graph.tex} +%\input{linux.tex} +\input{mmx.tex} +%\input{printer.tex} +%\input{sockets.tex} +%\input{strings.tex} +\end{document} diff --git a/docs/optex/Makefile b/docs/optex/Makefile new file mode 100644 index 0000000000..001c766f68 --- /dev/null +++ b/docs/optex/Makefile @@ -0,0 +1,53 @@ +####################################################################### +# +# Makefile to compile all examples and convert them to LaTeX +# +####################################################################### + +# Compiler +PP=ppc386 + +# Unit directory +# UNITDIR=/usr/lib/ppc/0.99.0/linuxunits + + +# Any options you wish to pass. +PPOPTS= + +# Script to convert the programs to LaTeX examples which can be included. +PP2TEX=pp2tex + +# Script to collect all examples in 1 file. +MAKETEX=make1tex + +####################################################################### +# No need to edit after this line. +####################################################################### + +ifdef UNITDIR +PPOPTS:=$(PPOPTS) -Up$(UNITDIR); +endif + +.SUFFIXES: .pp .tex + +.PHONY: all tex clean + +OBJECTS=optex + +TEXOBJECTS=$(addsuffix .tex, $(OBJECTS)) + +all : $(OBJECTS) + +tex : $(TEXOBJECTS) + +onetex : tex + $(MAKETEX) $(TEXOBJECTS) + +clean : + rm -f *.o *.s $(OBJECTS) $(TEXOBJECTS) + +$(OBJECTS): %: %.pp + $(PP) $(PPOPTS) $* + +$(TEXOBJECTS): %.tex: %.pp head.tex foot.tex + $(PP2TEX) $* diff --git a/docs/optex/README b/docs/optex/README new file mode 100644 index 0000000000..31b707d101 --- /dev/null +++ b/docs/optex/README @@ -0,0 +1,5 @@ +These are the example programs that appear in the FPC documentation. + +Units guide, chapter on CRT unit : + +optex.pp contains an example of the GetOpt function. diff --git a/docs/optex/foot.tex b/docs/optex/foot.tex new file mode 100644 index 0000000000..83788a402a --- /dev/null +++ b/docs/optex/foot.tex @@ -0,0 +1,2 @@ +\end{verbatim} +\end{FPKList} \ No newline at end of file diff --git a/docs/optex/head.tex b/docs/optex/head.tex new file mode 100644 index 0000000000..b2ed5b6603 --- /dev/null +++ b/docs/optex/head.tex @@ -0,0 +1,3 @@ +\begin{FPKList} +\item[Example] +\begin{verbatim} diff --git a/docs/optex/optex.pp b/docs/optex/optex.pp new file mode 100644 index 0000000000..2f730c36e9 --- /dev/null +++ b/docs/optex/optex.pp @@ -0,0 +1,92 @@ +program testopt; + +{ Program to depmonstrate the getopts function. } + +uses getopts; + +var c : char; + optionindex : integer; + theopts : array[1..7] of option; + +begin + with theopts[1] do + begin + name:='add'; + has_arg:=1; + flag:=nil; + value:=#0; + end; + with theopts[2] do + begin + name:='append'; + has_arg:=0; + flag:=nil; + value:=#0; + end; + with theopts[3] do + begin + name:='delete'; + has_arg:=1; + flag:=nil; + value:=#0; + end; + with theopts[4] do + begin + name:='verbose'; + has_arg:=0; + flag:=nil; + value:=#0; + end; + with theopts[5] do + begin + name:='create'; + has_arg:=1; + flag:=nil; + value:='c' + end; + with theopts[6] do + begin + name:='file'; + has_arg:=1; + flag:=nil; + value:=#0; + end; + with theopts[7] do + begin + name:=''; + has_arg:=0; + flag:=nil; + end; + c:=#0; + repeat + c:=getlongopts('abc:d:012',@theopts[1],optionindex); + case c of + '1','2','3','4','5','6','7','8','9' : + begin + writeln ('Got optind : ',c) + end; + #0 : begin + write ('Long option : ',theopts[optionindex].name); + if theopts[optionindex].has_arg>0 then + writeln (' With value : ',optarg) + else + writeln + end; + 'a' : writeln ('Option a.'); + 'b' : writeln ('Option b.'); + 'c' : writeln ('Option c : ', optarg); + 'd' : writeln ('Option d : ', optarg); + '?',':' : writeln ('Error with opt : ',optopt); + end; { case } + until c=endofoptions; + if optind<=paramcount then + begin + write ('Non options : '); + while optind<=paramcount do + begin + write (paramstr(optind),' '); + inc(optind) + end; + writeln + end +end. diff --git a/docs/optex/pp2tex b/docs/optex/pp2tex new file mode 100644 index 0000000000..3a5cd6a448 --- /dev/null +++ b/docs/optex/pp2tex @@ -0,0 +1,5 @@ +#!/bin/sh +# Simply paste a header and footer to the program. +cat head.tex > $1.tex +cat $1.pp >> $1.tex +cat foot.tex >> $1.tex diff --git a/docs/printer.tex b/docs/printer.tex new file mode 100644 index 0000000000..47ce567703 --- /dev/null +++ b/docs/printer.tex @@ -0,0 +1,62 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\chapter{The PRINTER unit.} +This chapter describes the PRINTER unit for Free Pascal. It was written for +\dos by Florian kl\"ampfl, and +it was written for \linux by Micha\"el Van Canneyt. Its basic functionality +is the same for both systems. + +The chapter is divided in 2 sections: +\begin{itemize} +\item The first section lists types, constants and variables from the +interface part of the unit. +\item The second section describes the functions defined in the unit. +\end{itemize} + +\section {Types, Constants and variables : } +\begin{verbatim} +var + lst : text; +\end{verbatim} +\var{Lst} is the standard printing device. \\ On \linux, +\var{Lst} is set up using \var{AssignLst('/tmp/PID.lst')}. +You can change this behaviour at compile time, setting the DefFile constant. +\section {Procedures and functions} +\procedure {AssignLst}{ ( Var F : text; ToFile : string[255])} +{ \linux only. \\ + Assigns to F a printing device. ToFile is a string with the following form: +\begin{itemize} +\item \var{ '|filename options'} : This sets up a pipe with the program filename, + with the given options, such as in the popen() call. +\item \var{ 'filename'} : Prints to file filename. Filename can contain the string 'PID' + (No Quotes), which will be replaced by the PID of your program. + When closing lst, the file will be sent to lpr and deleted. + (lpr should be in PATH) + +\item \var {'filename|'} Idem as previous, only the file is NOT sent to lpr, nor is it + deleted. + (useful for opening /dev/printer or for later printing) +\end{itemize} +} +{ Errors are reported in Linuxerror.} +{\seem{lpr}{1}} + +\input{printex/printex.tex} \ No newline at end of file diff --git a/docs/printex/Makefile b/docs/printex/Makefile new file mode 100644 index 0000000000..825cb45407 --- /dev/null +++ b/docs/printex/Makefile @@ -0,0 +1,53 @@ +####################################################################### +# +# Makefile to compile all examples and convert them to LaTeX +# +####################################################################### + +# Compiler +PP=ppc386 + +# Unit directory +# UNITDIR=/usr/lib/ppc/0.99.0/linuxunits + + +# Any options you wish to pass. +PPOPTS= + +# Script to convert the programs to LaTeX examples which can be included. +PP2TEX=pp2tex + +# Script to collect all examples in 1 file. +MAKETEX=make1tex + +####################################################################### +# No need to edit after this line. +####################################################################### + +ifdef UNITDIR +PPOPTS:=$(PPOPTS) -Up$(UNITDIR); +endif + +.SUFFIXES: .pp .tex + +.PHONY: all tex clean + +OBJECTS=printex + +TEXOBJECTS=$(addsuffix .tex, $(OBJECTS)) + +all : $(OBJECTS) + +tex : $(TEXOBJECTS) + +onetex : tex + $(MAKETEX) $(TEXOBJECTS) + +clean : + rm -f *.o *.s $(OBJECTS) $(TEXOBJECTS) + +$(OBJECTS): %: %.pp + $(PP) $(PPOPTS) $* + +$(TEXOBJECTS): %.tex: %.pp head.tex foot.tex + $(PP2TEX) $* diff --git a/docs/printex/README b/docs/printex/README new file mode 100644 index 0000000000..2520838205 --- /dev/null +++ b/docs/printex/README @@ -0,0 +1,5 @@ +These are the example programs that appear in the FPC documentation. + +Units guide, chapter on Printer unit : + +printex.pp contains an example of the AssignLst function. diff --git a/docs/printex/foot.tex b/docs/printex/foot.tex new file mode 100644 index 0000000000..83788a402a --- /dev/null +++ b/docs/printex/foot.tex @@ -0,0 +1,2 @@ +\end{verbatim} +\end{FPKList} \ No newline at end of file diff --git a/docs/printex/head.tex b/docs/printex/head.tex new file mode 100644 index 0000000000..b2ed5b6603 --- /dev/null +++ b/docs/printex/head.tex @@ -0,0 +1,3 @@ +\begin{FPKList} +\item[Example] +\begin{verbatim} diff --git a/docs/printex/pp2tex b/docs/printex/pp2tex new file mode 100644 index 0000000000..3a5cd6a448 --- /dev/null +++ b/docs/printex/pp2tex @@ -0,0 +1,5 @@ +#!/bin/sh +# Simply paste a header and footer to the program. +cat head.tex > $1.tex +cat $1.pp >> $1.tex +cat foot.tex >> $1.tex diff --git a/docs/printex/printex.pp b/docs/printex/printex.pp new file mode 100644 index 0000000000..16ad1b7658 --- /dev/null +++ b/docs/printex/printex.pp @@ -0,0 +1,23 @@ +program testprn; + +uses printer; + +var i : integer; + f : text; + +begin + writeln ('Test of printer unit'); + writeln ('Writing to lst...'); + for i:=1 to 80 do writeln (lst,'This is line ',i,'.'#13); + close (lst); + writeln ('Done.'); + {$ifdef linux} + writeln ('Writing to pipe...'); + assignlst (f,'|/usr/bin/lpr -m'); + rewrite (f); + for i:=1 to 80 do writeln (f,'This is line ',i,'.'#13); + close (f); + writeln ('Done.') + {$endif} +end. + diff --git a/docs/prog.tex b/docs/prog.tex new file mode 100644 index 0000000000..ec8956071a --- /dev/null +++ b/docs/prog.tex @@ -0,0 +1,2291 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\documentclass{report} +\usepackage{a4} +\usepackage{html} +\latex{\usepackage{multicol}} +\latex{\usepackage{fpkman}} +\html{\input{fpk-html.tex}} +% define the version number here, and not in the fpk.sty !!! +\newcommand{\fpkversion}{0.9.7} +\newcommand{\remark}[1]{\par$\rightarrow$\textbf{#1}\par} +\newcommand{\olabel}[1]{\label{option:#1}} +% We should change this to something better. See \seef etc. +\begin{document} +\title{Free Pascal \\ Programmer's manual} +\docdescription{Programmer's manual for \fpk, version \fpkversion} +\docversion{1.0} +\date{July 1997} +\author{Micha\"el Van Canneyt} +\maketitle +\tableofcontents +\newpage + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Introduction +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section*{About this document} +This is the programmer's manual for \fpk. + +It describes some of the peculiarities of the \fpk compiler, and provides a +glimp of how the compiler generates its code, and how you can change the +generated code. It will not, however, provide you with a detailed account of +the inner workings of the compiler, nor will it tell you how to use the +compiler (described in the \userref). It also will not describe the inner +workings of the Run-Time Library (RTL). The best way to learn about the way +the RTL is implemented is from the sources themselves. + +The things described here are useful if you want to do things which need +greater flexibility than the standard Pascal language constructs. +(described in the \refref) + +Since the compiler is continuously under development, this document may get +out of date. Wherever possible, the information in this manual will be +updated. If you find something which isn't correct, or you think something + is missing, feel free to contact me\footnote{at +\var{michael@tfdec1.fys.kuleuven.ac.be}}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Compiler switches +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Compiler directives} +\label{ch:CompSwitch} +\fpk supports compiler directives in your source file. They are not the same +as Turbo Pascal directives, although some are supported for compatibility. +There is a distinction between local and global directives; local directives +take effect from the moment they are encountered, global directives have an +effect on all of the compiled code. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Local switches +\section{Local directives} +\label{se:LocalSwitch} +Local directives have no command-line counterpart. They influence the +compiler's behaviour from the moment they're encountered until the moment +another switch annihilates their behaviour, or the end of the unit or +program is reached. + +\subsection{\var{\$F} : Far or near functions} +This directive is recognized for compatibility with Turbo Pascal. Under the +32-bit programming model, the concept of near and far calls have no meaning, +hence the directive is ignored. A warning is printed to the screen, telling +you so. + +As an example, : the following piece of code : +\begin{verbatim} +{$F+} + +Procedure TestProc; + +begin + Writeln ('Hello From TestProc'); +end; + +begin + testProc +end. +\end{verbatim} +Generates the following compiler output: +\begin{verbatim} +malpertuus: >pp -vw testf +Compiler: ppc386 +Units are searched in: /home/michael;/usr/bin/;/usr/lib/ppc/0.9.1/linuxunits +Target OS: Linux +Compiling testf.pp +testf.pp(1) Warning: illegal compiler switch +7739 kB free +Calling assembler... +Assembled... +Calling linker... +12 lines compiled, + 1.00000000000000E+0000 +\end{verbatim} +You can see that the verbosity level was set to display warnings. + +If you declare a function as \var{Far} (this has the same effect as setting it +between \var{\{\$F+\}...\{\$F-\}} directives), the compiler also generates a +warning : +\begin{verbatim} +testf.pp(3) Warning: FAR ignored +\end{verbatim} + +The same story is true for procedures declared as \var{Near}. The warning +displayed in that case is: +\begin{verbatim} +testf.pp(3) Warning: NEAR ignored +\end{verbatim} + +\subsection{\var{\$I} : Input/Output checking} +The \var{\{\$I-\}} directive tells the compiler not to generate input/output +checking code in your program. If you compile using the \var{-Ci} compiler +switch, the \fpk compiler inserts input/output +checking code after every input/output call in your program. If an error +occurred during input or output, then a run-time error will be generated. +Use this switch if you wish to avoid this behavior. +If you still want to check if something went wrong, you can use the +\var{IOResult} function to see if everything went without problems. + +Conversely, \var{\{\$I+\}} will turn error-checking back on, until another +directive is encountered which turns it off again. + +The most common use for this switch is to check if the opening of a file +went without problems, as in the following piece of code: +\begin{verbatim} +... +assign (f,'file.txt'); +{$I-} +rewrite (f); +{$I+} +if IOResult<>0 then + begin + Writeln ('Error opening file : "file.txt"'); + exit + end; +... +\end{verbatim} + +\subsection{\var{\$I} : Include file } +The \var{\{\$I filename\}} directive tells the compiler to read further +statements from the file \var{filename}. The statements read there will be +inserted as if they occurred in the current file. + +The compiler will append the \file{.pp} extension to the file if you don't +specify an extension yourself. Do not put the filename between quotes, as +they will be regarded as part of the file's name. + +You can nest included files, but not infinitely deep. The number of files is +restricted to the number of file descriptors available to the \fpk compiler. + +Contrary to Turbo Pascal, include files can cross blocks. I.e. you can start +a block in one file (with a \var{Begin} keyword) and end it in another (with +a \var{End} keyword). The smallest entity in an include file must be a token, +i.e. an identifier, keyword or operator. + +\subsection{\var{\$L} : Link object file} +The \var{\{\$L filename\}} directive tells the compiler that the file \file{filename} +should be linked to your program. You can only use this directive in a +program. If you do use it in a unit, the compiler will not complain, but +simply ignores the directive. + +The compiler will {\em not} look for the file in the unit path. +The name will be passed to the linker {\em exactly} as you've typed it. + +Since the files name is passed directly to the linker, this means that on +\linux systems, the name is case sensitive, and must be typed exactly as it +appears on your system. + +{\em Remark :} Take care that the object file you're linking is in a +format the linker understands. Which format this is, depends on the platform +you're on. Typing \var{ld} on th command line gives a list of formats +\var{ld} knows about. + +You can pass other files and options to the linker using the \var{-k} +command-line option. You can specify more than one of these options, and +they +will be passed to the linker, in the order that you specified them on the +command line, just before the names of the object files that must be linked. + +% Assembler type +\subsection{\var{\$I386\_XXX} : Specify assembler format} +This switch informs the compiler what kind of assembler it can expect in an +\var{asm} block. The \var{XXX} should be replaced by one of the following: +\begin{description} +\item [att\ ] Indicates that \var{asm} blocks contain AT\&T syntax assembler. +\item [intel\ ] Indicates that \var{asm} blocks contain Intel syntax +assembler. +\item [direct\ ] Tells the compiler that asm blocks should be copied +directly to the assembler file. +\end{description} +These switches are local, and retain their value to the end of the unit that +is compiled, unless they are replaced by another directive of the same type. +The command-line switch that corresponds to this switch is \var{-R}. + + +\subsection{\var{\$MMX} : MMX support} +As of version 0.9.8, \fpk supports optimization for the \textbf{MMX} Intel +processor (see also \ref{ch:MMXSupport}). This optimizes certain code parts for the \textbf{MMX} Intel +processor, thus greatly improving speed. The speed is noticed mostly when +moving large amounts of data. Things that change are +\begin{itemize} +\item Data with a size that is a multiple of 8 bytes is moved using the +\var{movq} assembler instruction, which moves 8 bytes at a time +\end{itemize} + +When \textbf{MMX} support is on, you aren't allowed to do floating point +arithmetic. You are allowed to move floating point data, but no arithmetic +can be done. If you wish to do floating point math anyway, you must first +switch of \textbf{MMX} support and clear the FPU using the \var{emms} +function of the \file{cpu} unit. + +The following example will make this more clear: +\begin{verbatim} +Program MMXDemo; + +uses cpu; + +var + d1 : double; + a : array[0..10000] of double; + i : longint; + +begin + d1:=1.0; +{$mmx+} + { floating point data is used, but we do _no_ arithmetic } + for i:=0 to 10000 do + a[i]:=d2; { this is done with 64 bit moves } +{$mmx-} + emms; { clear fpu } + { now we can do floating point arithmetic } + .... +end. +\end{verbatim} +See, however, the chapter on MMX (\ref{ch:MMXSupport}) for more information +on this topic. + +\subsection{\var{\$OUTPUT\_FORMAT} : Specify the output format} +\var{\{\$OUTPUT\_FORMAT format\}} has the same functionality as the \var{-A} +command-line option : It tells the compiler what kind of object file must be +generated. You can specify this switch \textbf{only} befor the \var{Program} +or \var{Unit} clause in your source file. The different kinds of formats are +shown in \seet{Formats}. + +\begin{FPKltable}{ll}{Formats generated by the compiler}{Formats} \hline +Switch value & Generated format \\ \hline +att & AT\&T assembler file. \\ +o & Unix object file.\\ +obj & OMF file.\\ +wasm & assembler for the Watcom assembler. \\ \hline +\end{FPKltable} + +\subsection{\var{\$V} : Var-string checking} + +When in the \var{+} state, the compiler checks that strings passed as +parameters are of the same, identical, string type as the declared +parameters of the procedure. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Global switches +\section{Global directives} +\label{se:GlobalSwitch} +Global directives affect the whole of the compilation process. That is why +they also have a command - line counterpart. The command-line counterpart is +given for each of the directives. + +\subsection{\var{\$A} : Align Data} + +This switch is recognized for Turbo Pascal Compatibility, but is not +yet implemented. The alignment of data will be different in any case, since +\fpk is a 32-bit compiler. + +\subsection{\var{\$B} : Complete boolean evaluation} + +This switch is understood by the \fpk compiler, but is ignored. The compiler +always uses shortcut evaluation, i.e. the evaluation of a boolean expression +is stopped once the result of the total exression is known with certainty. + +So, in the following example, the function \var{Bofu}, which has a boolean +result, will never get called. +\begin{verbatim} +If False and Bofu then + ... +\end{verbatim} + +\subsection{\var{\$D} : Debugging symbols} + +When this switch is on, the compiler inserts GNU debugging information in +the executable. The effect of this switch is the same as the command-line +switch \var{-g}. By default, insertion of debugging information is off. + +\subsection{\var{\$E} : Emulation of coprocessor} +This directive controls the emulation of the coprocessor. On the i386 +processor, it is supported for +compatibility with Turbo Pascal. The compiler itself doesn't do the emulation +of the coprocessor. Under \dos, the \dos extender does this, and under +\linux, the kernel takes care of the coprocessor support. + +If you use the Motorola 680x0 version, then the switch is recognized, as +there is no extender to emulate the coprocessor, so the compiler must do +that by itself. + +There is no command-line counterpart for this directive. + +\subsection{\var{\$G} : Generate 80286 code} + +This option is recognised for Turbo Pascal cmpatibility, but is ignored, +because the compiler needs at least a 386 or higher class processor. + + +\subsection{\var{\$L} : Local symbol information} + +This switch (not to be confused with the \var{\{\$L file\}} file linking +directive) is recognised for Turbo Pascal compatibility, but is ignored. +generation of symbol information is controlled by the \var{\$D} switch. + +\subsection{\var{\$N} : Numeric processing } + +This switch is recognised for Turbo Pascal compatibility, but is otherwise +ignored, since the compiler always uses the coprocessor for floating point +mathematics. + +\subsection{\var{\$O} : Overlay code generation } + +This switch is recognised for Turbo Pascal compatibility, but is otherwise +ignored, since the compiler requires a 386 or higher computer, with at +least 4 Mb. of ram. + +\subsection{\var{\$Q} : Overflow checking} +The \var{\{\$Q+\}} directive turns on integer overflow checking. +This means that the compiler inserts code to check for overflow when doing +computations with an integer. +When an overflow occurs, the run-time library will print a message +\var{Overflow at xxx}, and exit the program with exit code 1. + +Using the \var{\{\$Q-\}} switch switches off the overflow checking code +generation. + +The generation of overflow checking code can also be controlled +using the \var{-Co} command line compiler option (see \userref). + +\subsection{\var{\$R} : Range checking} +By default, the computer doesn't generate code to check the ranges of array +indices, enumeration types, subrange types, etc. Specifying the +\var{\{\$R+\}} switch tells the computer to generate code to check these +indices. If, at run-time, an index or enumeration type is specified that is +out of the declared range of the compiler, then a run-time error is +generated, and the program exits with exit code 1. + +The \var{\{\$R-\}} switch tells the compiler not to generate range checking +code. This may result in faulty program behaviour, but no run-time errors +will be generated. + +{\em Remark: } this has not been implemented completely yet. + +\subsection{\var{\$S} : Stack checking} +The \var{\{\$S+\}} directive tells the compiler to generate stack checking +code. This generates code to check if a stack overflow occurred, i.e. to see +whether the stack has grown beyond its maximally allowed size. If the stack +grows beyond the maximum size, then a run-time error is generated, and the +program will exit with exit code 1. + +Specifying \var{\{\$S-\}} will turn generation of stack-checking code off. + +There is no command-line switch which is equivalent to this directive. + +{\em Remark: } In principle, the stack is almost unlimited, +i.e. limited to the total free amount of memory on the computer. + + +\subsection{\var{\$X} : Extended syntax} +Extended syntax allows you to drop the result of a function. This means that +you can use a function call as if it were a procedure. Standard this feature +is on. You can switch it off using the \var{\{\$X-\}} directive. + +The following, for instance, will not compile : +\begin{verbatim} +function Func (var Arg : sometype) : longint; +begin +... { declaration of Func } +end; + +... + +{$X-} +Func (A); +\end{verbatim} +The reason this construct is supported is that +you may wish to call a function for certain side-effects it has, but you +don't need the function result. In this case you don't need to assign the +function result, saving you an extra variable. + +The command-line compiler switch \var{-Sa1} has the same effect as the +\var{\{\$X+\}} directive. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Using conditionals and macros +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Using conditionals, Messages and macros} +\label{ch:CondMessageMacro} +The \fpk compiler supports conditionals as in normal Turbo Pascal. It does, +however, more than that. It allows you to make macros which can be used in +your code, and it allows you to define messages or errors which will be +displayed when compiling. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Conditionals +\section{Conditionals} +\label{se:Conditionals} +The rules for using conditional symbols are the same as under Turbo Pascal. +Defining a symbol goes as follows: +\begin{verbatim} +{$Define Symbol } +\end{verbatim} +From this point on in your code, the compiler know the symbol \var{Symbol} +Symbols are, like the Pascal language, case insensitive. + +You can also define a symbol on the command line. the \var{-dSymbol} option +defines the symbol \var{Symbol}. You can specify as many symbols on the +command line as you want. + +Undefining an existing symbol is done in a similar way: +\begin{verbatim} +{$Undefine Symbol } +\end{verbatim} +If the symbol didn't exist yet, this doesn't do anything. If the symbol +existed previously, the symbol will be erased, and will not be recognized +any more in the code following the \verb|{$Undefine ...}| statement. + +You can also undefine symbols from the command line with the \var{-u} +command-line switch.. + +To compile code conditionally, depending on whether a symbol is defined or +not, you can enclose the code in a \verb|{$ifdef Symbol}| .. \verb|{$endif}| +pair. For instance the following code will never be compiled : +\begin{verbatim} +{$Undefine MySymbol} +{$ifdef Mysymbol} + DoSomething; + ... +{$endif} +\end{verbatim} + +Similarly, you can enclose your code in a \verb|{$Ifndef Symbol}| .. \verb|{$endif}| +pair. Then the code between the pair will only be compiled when the used +symbol doesn't exist. For example, in the following example, the call to the +\var{DoSomething} will always be compiled: +\begin{verbatim} +{$Undefine MySymbol} +{$ifndef Mysymbol} + DoSomething; + ... +{$endif} +\end{verbatim} + +You can combine the two alternatives in one structure, namely as follows +\begin{verbatim} +{$ifdef Mysymbol} + DoSomething; +{$else} + DoSomethingElse +{$endif} +\end{verbatim} +In this example, if \var{MySymbol} exists, then the call to \var{DoSomething} +will be compiled. If it doesn't exist, the call to \var{DoSomethingElse} is +compiled. + +The \fpk compiler defines some symbols before starting to compile your +program or unit. You can use these symbols to differentiate between +different versions of the compiler, and between different compilers. +In \seet{Symbols}, a list of pre-defined symbols is given. In that table, +you should change \var{v} with the version number of the compiler +you're using, \var{r} with the release number and \var{p} +with the patch-number of the compiler. 'OS' needs to be changed by the type +of operating system. Currently this can be one of \var{DOS}, \var{GO32V2}, +\var{LINUX}, \var{OS2} or \var{WIN32}. This symbol is undefined if you +specify a target that is different from the platform you're compiling on. +the \var{-TSomeOS} option on the command line will define the \var{SomeOS} symbol, +and will undefined the existing platform symbol\footnote{In versions prior to +0.9.4, this didn't happen, thus making Cross-compiling impossible.}. + +\begin{FPKltable}{c}{Symbols defined by the compiler.}{Symbols} \hline +Free \\ +VER\var{v} \\ +VER\var{v}\_\var{r} \\ +VER\var{v}\_\var{r}\_\var{p} \\ +OS \\ \hline +\end{FPKltable} + +As an example : Version 0.9.1 of the compiler, running on a Linux system, +defines the following symbols before reading the command line arguments: +\var{FPK}, \var{VER0}, \var{VER0\_9}, \var{VER0\_9\_1} and \var{LINUX}. +Specifying \var{-TOS2} on the command-line will undefine the \var{LINUX} +symbol, and will define the \var{OS2} symbol. + +{\em Remark: } Symbols, even when they're defined in the interface part of +a unit, are not available outside that unit. + +\fpk supports the \var{\{\$IFOPT \}} directive for Turbo Pascal +compatibility, but doesn't act on it. It always rejects the condition, so +code between \var{\{\$IFOPT \}} and \var{\{\$Endif\}} is never compiled. + +Except for the Turbo Pascal constructs, from version 0.9.8 and higher, +the \fpk compiler also supports a stronger conditional compile mechanism: +The \var{\{\$If \}} construct. + +The prototype of this construct is as follows : +\begin{verbatim} +{$If expr} + CompileTheseLines; +{$else} + BetterCompileTheseLines; +{$endif} +\end{verbatim} +In this directive \var{expr} is a Pascal expression which is evaluated using +strings, unless both parts of a comparision can be evaluated as numbers, +in which case they are evaluated using numbers\footnote{Otherwise +\var{\{\$If 8>54} would evaluate to \var{True}}. +If the complemete expression evaluates to \var{'0'}, then it is considered +false and rejected. Otherwise it is considered true and accepted. This may +have unsexpected consequences : +\begin{verbatim} +{$If 0} +\end{verbatim} +Will evaluate to \var{False} and be rejected, while +\begin{verbatim} +{$If 00} +\end{verbatim} +Will evaluate to \var{True}. + +You can use any Pascal operator to construct your expression : \var{=, <>, +>, <, >=, <=, AND, NOT, OR} and you can use round brackets to change the +precedence of the operators. + +The following example shows you many of the possibilities: +\begin{verbatim} +{$ifdef fpk} + +var + y : longint; +{$else fpk} + +var + z : longint; +{$endif fpk} + +var + x : longint; + +begin + +{$if (fpk_version=0) and (fpk_release>6) and (fpk_patch>4)} +{$info At least this is version 0.9.5} +{$else} +{$fatalerror Problem with version check} +{$endif} + +{$define x:=1234} +{$if x=1234} +{$info x=1234} +{$else} +{$fatalerror x should be 1234} +{$endif} + +{$if 12asdf and 12asdf} +{$info $if 12asdf and 12asdf is ok} +{$else} +{$fatalerror $if 12asdf and 12asdf rejected} +{$endif} + +{$if 0 or 1} +{$info $if 0 or 1 is ok} +{$else} +{$fatalerror $if 0 or 1 rejected} +{$endif} + +{$if 0} +{$fatalerror $if 0 accepted} +{$else} +{$info $if 0 is ok} +{$endif} + +{$if 12=12} +{$info $if 12=12 is ok} +{$else} +{$fatalerror $if 12=12 rejected} +{$endif} + +{$if 12<>312} +{$info $if 12<>312 is ok} +{$else} +{$fatalerror $if 12<>312 rejected} +{$endif} + + +{$if 12<=312} +{$info $if 12<=312 is ok} +{$else} +{$fatalerror $if 12<=312 rejected} +{$endif} + +{$if 121234>=312} +{$info $if 121234>=312 is ok} +{$else} +{$fatalerror $if 121234>=312 rejected} +{$endif} + +{$if 12<312} +{$info $if 12<312 is ok} +{$else} +{$fatalerror $if 12<312 rejected} +{$endif} + +{$if 122134>312} +{$info $if 122134>312 is ok} +{$else} +{$fatalerror $if 122134>312 rejected} +{$endif} +{$if a12=a12} +{$info $if a12=a12 is ok} +{$else} +{$fatalerror $if a12=a12 rejected} +{$endif} + +{$if a12<>z312} +{$info $if a12<>z312 is OK} +{$else} +{$fatalerror $if a12<>z312 rejected} +{$endif} + + +{$if a12<=z312} +{$info $if a12<=z312 is ok} +{$else} +{$fatalerror $if a12<=z312 rejected} +{$endif} + +{$if z121234>=a312} +{$info $if z121234>=a312 is OK} +{$else} +{$fatalerror $if z121234>=a312 rejected} +{$endif} + +{$if a12a312} +{$info $if z122134>a312 is OK} +{$else} +{$fatalerror $if z122134>a312 rejected} +{$endif} + +{$if not z122134>a312} +{$fatalerror $if not z122134>a312 accepted} +{$else} +{$info $if not z122134>a312 is OK} +{$endif} + +{$if not(0)} +{$info $if not(0) is OK} +{$else} +{$fatalerror $if not(0) rejected} +{$endif} + +{$info *************************************************} +{$info * Now have to follow at least 2 error messages: *} +{$info *************************************************} + +{$if not(0} +{$endif} + +{$if not(<} +{$endif} + +end. +\end{verbatim} +As you can see from the example, this construct isn't useful when used +with normal symbols, but it is if you use macros, which are explained in +\sees{Macros}, they can be very useful. When trying this example, you must +switch on macro support, with the \var{-Sm} command-line switch. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Macros +\section{Messages} +\label{se:Messages} +\fpk lets you define normal, warning and error messages in your code. +Messages can be used to display useful information, such as copyright +notices, a list of symbols that your code reacts on etc. + +Warnings can be used if you think some part of your code is still buggy, or +if you think that a certain combination of symbols isn't useful. In general +anything which may cause problems when compiling. + +Error messages can be useful if you need a certain symbol to be defined +to warn that a certain variable isn't defined or so, or when the compiler +version isn't suitable for your code. + +The compiler treats these messages as if they were generated by the +compiler. This means that if you haven't turned on warning messages, the +warning will not e displayed. Errors are always displayed, and the compiler +stops as if an error had occurred. + +For messages, the syntax is as follows : +\begin{verbatim} +{$Message Message text } +\end{verbatim} +Or +\begin{verbatim} +{$Info Message text } +\end{verbatim} +For notes: +\begin{verbatim} +{$Note Message text } +\end{verbatim} +For warnings: +\begin{verbatim} +{$Warning Warning Message text } +\end{verbatim} +For errors : +\begin{verbatim} +{$Error Error Message text } +\end{verbatim} +Lastly, for fatal errors : +\begin{verbatim} +{$FatalError Error Message text } +\end{verbatim} +or +\begin{verbatim} +{$Stop Error Message text } +\end{verbatim} +The difference between \var{\$Error} and \var{\$FatalError} or \var{\$Stop} +messages is that when the compiler encounters an error, it still continues +to compile. With a fatal error, the compiler stops. + +{\em Remark :} You cannot use the '\var{\}}' character in your message, since +this will be treated as the closing brace of the message. + +As an example, the following piece of code will generate an error when +the symbol \var{RequiredVar} isn't defined: +\begin{verbatim} +{$ifndef RequiredVar} +{$Error Requiredvar isn't defined !} +{$endif} +\end{verbatim} +But the compiler will continue to compile. It will not, however, generate a +unit file or a program (since an error occurred). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Macros +\section{Macros} +\label{se:Macros} +Macros are very much like symbols in their syntax, the difference is that +macros have a value whereas a symbol simply is defined or is not defined. +If you want macro support, you need to specify the \var{-Sm} command-line +switch, otherwise your macro will be regarded as a symbol. + +Defining a macro in your program is done in the same way as defining a symbol; +in a \var{\{\$define \}} preprocessor statement\footnote{In compiler +versions older than 0.9.8, the assignment operator for a macros wasn't +\var{:=}, but \var{=}}: +\begin{verbatim} +{$define ident:=expr} +\end{verbatim} +If the compiler encounters \var{ident} in the rest of the source file, it +will be replaced immediately by \var{expr}. This replacement works +recursive, meaning that when the compiler expanded one of your macros, it +will look at the resulting expression again to see if another replacement +can be made. You need to be careful with this, because an infinite loop can +occur in this manner. + +Here are two examples which illustrate the use of macros: +\begin{verbatim} +{$define sum:=a:=a+b;} +... +sum { will be expanded to 'a:=a+b;' + remark the absence of the semicolon} +... +{$define b:=100} +sum { Will be expanded recursively to a:=a+100; } +... +\end{verbatim} +The previous example could go wrong : +\begin{verbatim} +{$define sum:=a:=a+b;} +... +sum { will be expanded to 'a:=a+b;' + remark the absence of the semicolon} +... +{$define b=sum} { DON'T do this !!!} +sum { Will be infinitely recursively expanded... } +... +\end{verbatim} +On my system, the last example results in a heap error, causing the compiler +to exit with a run-time error 203. + +{\em Remark: } Macros defined in the interface part of a unit are not +available outside that unit ! They can just be used as a notational +convenience, or in conditional compiles. + +By default, from version 0.9.8 of the compiler on, the compiler predefines three +macros, containing the version number, the release number and the patch +number. They are listed in \seet{DefMacros}. +\begin{FPKltable}{ll}{Predefined macros}{DefMacros} \hline +Symbol & Contains \\ \hline +\var{FPK\_VERSION} & The version number of the compiler. \\ +\var{FPK\_RELEASE} & The release number of the compiler. \\ +\var{FPK\_PATCH} & The patch number of the compiler. \\ +\hline +\end{FPKltable} + +{\em Remark: } Don't forget that macros support isn't on by default. You +need to compile with the \var{-Sm} command-line switch. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Using assembly language +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Using assembly language} +\label{ch:AsmLang} +\fpk supports inserting of assembler instructions in your code. The +mechanism for this is the same as under Turbo Pascal. There are, however +some substantial differences, as will be explained in the following. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% AT&T syntax +\section{AT\&T Syntax} +\label{se:AttSyntax} +\fpk uses the \gnu \var{as} assembler to generate its object files. Since +the \gnu assembler uses AT\&T assembly syntax, the code you write should +use the same syntax. The differences between AT\&T and Intel syntax as used +in Turbo Pascal are summarized in the following: +\begin{itemize} +\item The opcode names include the size of the operand. In general, one can +say that the AT\&T opcode name is the Intel opcode name, suffixed with a +'\var{l}', '\var{w}' or '\var{b}' for, respectively, longint (32 bit), +word (16 bit) and byte (8 bit) memory or register references. As an example, +the Intel construct \mbox{'\var{mov al bl}} is equivalent to the AT\&T style '\var{movb +\%bl,\%al}' instruction. +\item AT\&T immediate operands are designated with '\$', while Intel syntax +doesn't use a prefix for immediate operands. Thus the Intel construct +'\var{mov ax, 2}' becomes '\var{movb \$2, \%al}' in AT\&T syntax. +\item AT\&T register names are preceded by a '\var{\%}' sign. +They are undelimited in Intel syntax. +\item AT\&T indicates absolute jump/call operands with '\var{*}', Intel +syntax doesn't delimit these addresses. +\item The order of the source and destination operands are switched. AT\&T +syntax uses '\var{Source, Dest}', while Intel syntax features '\var{Dest, +Source}'. Thus the Intel construct '\var{add eax, 4}' transforms to +'\var{addl \$4, \%eax}' in the AT\&T dialect. +\item Immediate long jumps are prefixed with the '\var{l}' prefix. Thus the +Intel '\var{call/jmp section:offset'} is transformed to '\var{lcall/ljmp +\$section,\$offset}'. Similarly the far return is '\var{lret}', instead of the +Intel '\var{ret far}'. +\item Memory references are specified differently in AT\&T and Intel +assembly. The Intel indirect memory reference +\begin{quote} +\var{Section:[Base + Index*Scale + Offs]} +\end{quote} +is written in AT\&T syntax as : +\begin{quote} +\var{Section:Offs(Base,Index,Scale)} +\end{quote} +Where \var{Base} and \var{Index} are optional 32-bit base and index +registers, and \var{Scale} is used to multiply \var{Index}. It can take the +values 1,2,4 and 8. The \var{Section} is used to specify an optional section +register for the memory operand. +\end{itemize} + +More information about the AT\&T syntax can be found in the \var{as} manual, +although the following differences with normal AT\&T assembly must be taken +into account : +\begin{itemize} +\item Only the following directives are presently supported: + \begin{description} +\item[.byte] +\item[.word] +\item[.long] +\item[.ascii] +\item[.asciz] +\item[.globl] +\end{description} +\item The following directives are recognized but are not + supported: +\begin{description} +\item[.align] +\item[.lcomm] +\end{description} +Eventually they will be supported. +\item Directives are case sensitive, other identifiers are not case sensitive. +\item Contrary to GAS local labels/symbols {\em must} start with \var{.L} +\item The nor operator \var{'!'} is not supported. +\item String expressions in operands are not supported. +\item Constant expressions which represent memory references are not +allowed even though constant immediate value expressions are supported. \\ +examples: +\begin{verbatim} +const myid = 10; +... +movl $myid,%eax -- allowed +movl myid(%esi),%eax -- not allowed. +\end{verbatim} +\item When the \var{.globl} directive is found, the symbol following + it is made public and is immediately emitted. + Therefore label names with this name will be ignored. +\item Only Single and Double FPU opcodes are supported. +\end{itemize} + +The AT\&T inline assembler supports the following macros : +\begin{description} +\item [\_\_RESULT] represents the function result return value. +\item [\_\_SELF] represents the object method pointer in methods. +\item [\_\_OLDEBP] represents the old base pointer in recusrive routines. +\end{description} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Intel syntax +\section{Intel syntax} +\label{se:Intel} + +As of version 0.9.7, \fpk supports Intel syntax in it's \var{asm} blocks. +The Intel syntax in your \var{asm} block is converted to AT\&T syntax by the +compiler, after which it is inserted in the compiled source. +The supported assembler constructions are a subset of the normal assembly +syntax. In what follows we specify what constructs are not supported in +\fpk, but which exist in Turbo Pascal: + +\begin{itemize} +\item The \var{TBYTE} qualifier is not supported. +\item The \var{\&} identifier override is not supported. +\item The \var{HIGH} operator is not supported. +\item The \var{LOW} operator is not supported. +\item The \var{OFFSET} and \var{SEG} operators are not supported. + use \var{LEA} and the various \var{Lxx} instructions instead. +\item Expressions with constant strings are not allowed. +\item Access to record fields via parenthesis is not allowed +\item Typecasts with normal pascal types are not allowed, only + recognized assembler typecasts are allowed.\\ Example: +\begin{verbatim} +mov al, byte ptr MyWord -- allowed, +mov al, byte(MyWord) -- allowed, +mov al, shortint(MyWord) -- not allowed. +\end{verbatim} +\item Pascal type typecasts on constants are not allowed. \\ +Example: +\begin{verbatim} +const s= 10; const t = 32767; +\end{verbatim} +in Turbo Pascal: +\begin{verbatim} +mov al, byte(s) -- useless typecast. +mov al, byte(t) -- syntax error! +\end{verbatim} +In this parser, either of those cases will give out a syntax error. +\item Constant references expressions with constants only are not + allowed (in all cases they do not work in protected mode, + under linux i386). \\ Examples: +\begin{verbatim} +mov al,byte ptr ['c'] -- not allowed. +mov al,byte ptr [100h] -- not allowed. +\end{verbatim} + (This is due to the limitation of Turbo Assembler). +\item Brackets within brackets are not allowed +\item Expressions with segment overrides fully in brackets are +presently not supported, but they can easily be implemented +in BuildReference if requested. \\ Example: +\begin{verbatim} +mov al,[ds:bx] -- not allowed +\end{verbatim} +use instead: +\begin{verbatim} +mov al,ds:[bx] +\end{verbatim} +\item Possible allowed indexing are as follows: +\begin{itemize} +\item \var{Sreg:[REG+REG*SCALING+/-disp]} +\item \var{SReg:[REG+/-disp]} +\item \var{SReg:[REG]} +\item \var{SReg:[REG+REG+/-disp]} +\item \var{SReg:[REG+REG*SCALING]} +\end{itemize} +Where \var{Sreg} is optional and specifies the segment override. +{\em Notes:} +\begin{enumerate} +\item The order of terms is important contrary to Turbo Pascal. +\item The Scaling value must be a value, and not an identifier +to a symbol.\\ Examples: +\begin{verbatim} +const myscale = 1; +... +mov al,byte ptr [esi+ebx*myscale] -- not allowed. +\end{verbatim} +use: +\begin{verbatim} +mov al, byte ptr [esi+ebx*1] +\end{verbatim} +\end{enumerate} +\item Possible variable identifier syntax is as follows: + (Id = Variable or typed constant identifier.) +\begin{enumerate} +\item \var{ID} +\item \var{[ID]} +\item \var{[ID+expr]} +\item \var{ID[expr]} +\end{enumerate} + Possible fields are as follow: +\begin{enumerate} +\item \var{ID.subfield.subfield ...} +\item \var{[ref].ID.subfield.subfield ...} +\item \var{[ref].typename.subfield ...} +\end{enumerate} +\item Local Labels: Contrary to Turbo Pascal, local labels, must +at least contain one character after the local symbol indicator.\\ +Example: +\begin{verbatim} +@: -- not allowed +\end{verbatim} + use instead, for example: +\begin{verbatim} +@1: -- allowed +\end{verbatim} +\item Contrary to Turbo Pascal local references cannot be used as references, + only as displacements. \\ example: +\begin{verbatim} +lds si,@mylabel -- not allowed +\end{verbatim} +\item Contrary to Turbo Pascal, \var{SEGCS}, \var{SEGDS}, \var{SEGES} and +\var{SEGSS} segment overrides are presently not supported. + (This is a planned addition though). +\item Contrary to Turbo Pascal where memory sizes specifiers can + be practically anywhere, the \fpk Intel inline assembler requires + memory size specifiers to be outside the brackets. \\ + example: +\begin{verbatim} +mov al,[byte ptr myvar] -- not allowed. +\end{verbatim} + use: +\begin{verbatim} +mov al,byte ptr [myvar] -- allowed. +\end{verbatim} +\item Base and Index registers must be 32-bit registers. + (limitation of the GNU Assembler). +\item \var{XLAT} is equivalent to \var{XLATB}. +\item Only Single and Double FPU opcodes are supported. +\item Floating point opcodes are currently not supported + (except those which involve only floating point registers). +\end{itemize} + +The Intel inline assembler supports the following macros : +\begin{description} +\item [@Result] represents the function result return value. +\item [Self] represents the object method pointer in methods. +\end{description} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Calling mechanism +\section{Calling mechanism} +\label{se:Calling} +Procedures and Functions are called with their parameters on the stack. +Contrary to Turbo Pascal, {\em all} parameters are pushed on the stack, and +they are pushed {\em right} to {\em left}, instead of left to right for +Turbo Pascal. This is especially important if you have some assembly +subroutines in Turbo Pascal which you would like to translate to \fpk. + +Function results are returned in the first register, if they fit in the +register. For more information on this, see \sees{Stack} + +The registers are {\em not} saved when calling a function or procedure. If +you want to call a procedure or function from assembly language, you must +save any registers you wish to preserve. + +The first thing a procedure does is saving the base pointer, and setting the +base (\var{\%ebp}) pointer equal to the stack pointer (\var{\%esp}). +References to the pushed parameters and local variables are constructed +using the base pointer. + +In practice this amounts to the following assembly code as the procedure or +function header : +\begin{verbatim} + pushl %ebp + movl %esp,%ebp +\end{verbatim} + +When the procedure or function exits, it clears the stack by means of the +\var{RET xx} call, where \var{xx} is the total size of the pushed parameters +on the stack. Thus, in case parameters with a total size of \var{xx} have +been passed to a function, the generated exit sequence looks as follows: +\begin{verbatim} + leave + ret $xx +\end{verbatim} + +When you want your code to be called by a C library or used in a C +program, you will run into trouble because of this calling mechanism. In C, +the calling procedure is expected to clear the stack, not the called +procedure. To avoid this problem, \fpk supports the \var{export} modifier. +Procedures that are defined using the export modifier, use a C-compatible +calling mechanism. This means that they can be called from a C program or +library, or that you can use them as a callback function. + +This also means that you cannot call this procedure or function from your +own program, since your program uses the Pascal calling convention. +However, in the exported function, you can of course call other Pascal +routines. + +Technically, the C calling mechanism is implemented by generating the +following exit sequence at the end of your function or procedure: +\begin{verbatim} + leave {Copies EBP to ESP, pops EBP from the stack.} + ret +\end{verbatim} +Comparing this exit sequence with the previous one makes it clear why you +cannot call this procedure from within Pascal: The arguments still are on +the stack when the procedure exits. + +As of version 0.9.8, the \fpk compiler supports also the \var{cdecl} and +\var{stdcall} modifiers, as found in Delphi. The \var{cdecl} modifier does +the same as the \var{export} modifier, and \var{stdcall} does nothing, since +\fpk pushes the paramaters from right to left by default. + +All this is summarized in \seet{Calling}. The first column lists the +modifier you specify for a procedure declaration. The second one lists the +order the paramaters are pushed on the stack. The third column specifies who +is responsible for cleaning the stack: the caller or the called function. +Finally, the last column specifies if registers are used to pass parameters +to the function. + +\begin{FPKltable}{llll}{Calling mechanisms in \fpk}{Calling}\hline +Modifier & Pushing order & Stack cleaned by & Parameters in registers \\ +\hline +(none) & Right-to-left & Function & No \\ +cdecl & Right-to-left & Caller & No \\ +export & Right-to-left & Caller & No \\ +stdcall & Right-to-left & Function & No \\ \hline +\end{FPKltable} + +More about this can be found in \seec{Linking} on linking. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Telling the compiler what registers have changed +\section{Telling the compiler what registers have changed} +\label{se:RegChanges} +When the compiler uses variables, it sometimes stores them, or the result of +some calculations, in the processor registers. If you insert assembler code +in your program that modifies the processor registers, then this may +interfere with the compiler's idea about the registers. To avoid this +problem, \fpk allows you to tell the compiler which registers have changed. +The compiler will then avoid using these registers. Telling the compiler +which registers have changed, is done by specifying a set of register names +behind an assembly block, as follows: +\begin{verbatim} +asm + ... +end ['R1',...,'Rn']; +\end{verbatim} +Here \var{R1} to \var{Rn} are the names of the (extended) registers you +modify in your assembly code. They can be one of \var{'EAX', 'EBX', 'ECX', +'EDX', 'EDI', 'ESI'} for the Intel processor. + +As an example : +\begin{verbatim} + asm + movl BP,%eax + movl 4(%eax),%eax + movl %eax,__RESULT + end ['EAX']; +\end{verbatim} +This example tells the compiler that the \var{EAX} register was modified. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Linking issues +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Linking issues} +\label{ch:Linking} +When you only use Pascal code, and Pascal units, then you will not see much +of the part that the linker plays in creating your executable. +The linker is only called when you compile a program. When compiling units, +the linker isn't invoked. + +However, there are times that you want to C libraries, or to external +object files that are generated using a C compiler (or even another pascal +compiler). The \fpk compiler can generate calls to a C function, +and can generate functions that can be called from C (exported functions). +However, these exported functions cannot be called from +inside Pascal anymore. More on these calling conventions can be found in +\sees{Calling}. + +In general, there are 2 things you must do to use a function that resides in +an external library or object file: +\begin{enumerate} +\item You must make a pascal declaration of the function or procedure you +want to use. +\item You must tell the compiler where the function resides, i.e. in what +object file or what library, so the compiler can link the necessary code in. +\end{enumerate} +The following sections attempt to explain how to do this. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Declaring an external function or procedure +\section{Declaring an external function or procedure} +\label{se:ExternalDeclaration} + +The first step in using external code blocks is declaring the function you +want to use. \fpk supports Delphi syntax, i.e. you must use the +\var{external} directive. + +There exist four variants of the external direcive : +\begin{enumerate} +\item A simple external declaration: +\begin{verbatim} +Procedure ProcName (Args : TPRocArgs); external; +\end{verbatim} +The \var{external} directive tells the compiler that the function resides in +an external block of code. You can use this together with the \var{\{\$L \}} +or \var{\{\$LinkLib \}} directives to link to a function or procedure in a +library or external object file. + +\item You can give the \var{external} directive a library name as an +argument: +\begin{verbatim} +Procedure ProcName (Args : TPRocArgs); external 'Name'; +\end{verbatim} +This tells the compiler that the procedure resides in a library with name +\var{'Name'}. This method is equivalent to the following: +\begin{verbatim} +Procedure ProcName (Args : TPRocArgs);external; +{$LinkLib 'Name'} +\end{verbatim} +\item The \var{external} can also be used with two arguments: +\begin{verbatim} +Procedure ProcName (Args : TPRocArgs); external 'Name' + name 'OtherProcName'; +\end{verbatim} +This has the same meaning as the previous declaration, only the compiler +will use the name \var{'OtherProcName'} when linking to the library. This +can be used to give different names to procedures and functions in an +external library. + +This method is equivalent to the following code: +\begin{verbatim} +Procedure OtherProcName (Args : TProcArgs); external; +{$LinkLib 'Name'} + +Procedure ProcName (Args : TPRocArgs); + +begin + OtherProcName (Args); +end; +\end{verbatim} +\item Lastly, onder \windows and \ostwo, there is a fourth possibility +to specify an external function: In \file{.DLL} files, functionas also have +a unique number (their index). It is possible to refer to these fuctions +using their index: +\begin{verbatim} +Procedure ProcName (Args : TPRocArgs); external 'Name' Index SomeIndex; +\end{verbatim} +This tells the compiler that the procedure \var{ProcName} resides in a +dynamic link library, with index {SomeIndex}. + +\em{Remark:} Note that this is ONLY available under \windows and \ostwo. +\end{enumerate} + +In earlier versions of the \fpk compiler, the following construct was +also possible : +\begin{verbatim} +Procedure ProcName (Args : TPRocArgs); [ C ]; +\end{verbatim} +This method is equivalent to the following statement: +\begin{verbatim} +Procedure ProcName (Args : TPRocArgs); cdecl; external; +\end{verbatim} +However, the \var{[ C ]} directive is deprecated, and may no longer be +supported in future versions of \fpk, therefore you should use the +\var{external} directive, with the \var{cdecl} directive, if needed. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Linking an object file in your program +\section{Explicitly linking an object file in your program} +\label{se:LinkIn} +Having declared the external function that resides in an object file, +you can use it as if it was defined in your own program or unit. +To produce an executable, you must still link the object file in. +This can be done with the \var{\{\$L 'file.o'\}} directive. + +This will cause the linker to link in the object file \file{file.o}. On +\linux systems, this filename is case sensitive. Under \dos, case isn't +important. Note that \var{file.o} must be in the current directory if you +don't specify a path. The linker will not search for \file{file.o} if it +isn't found. + +You cannot specify libraries in this way, it is for object files only. + +Here we present an example. Consider that you have some assembly routine that +calculates the nth Fibonacci number : +\begin{verbatim} +.text + .align 4 +.globl Fibonacci + .type Fibonacci,@function +Fibonacci: + pushl %ebp + movl %esp,%ebp + movl 8(%ebp),%edx + xorl %ecx,%ecx + xorl %eax,%eax + movl $1,%ebx + incl %edx +loop: + decl %edx + je endloop + movl %ecx,%eax + addl %ebx,%eax + movl %ebx,%ecx + movl %eax,%ebx + jmp loop +endloop: + movl %ebp,%esp + popl %ebp + ret +\end{verbatim} +Then you can call this function with the following Pascal Program: +\begin{verbatim} +Program FibonacciDemo; + +var i : longint; + +Function Fibonacci (L : longint):longint;cdecl;external; + +{$L fib.o} + +begin + For I:=1 to 40 do + writeln ('Fib(',i,') : ',Fibonacci (i)); +end. +\end{verbatim} +With just two commands, this can be made into a program : +\begin{verbatim} +as -o fib.o fib.s +pp fibo.pp +\end{verbatim} +This example supposes that you have your assembler routine in \file{fib.s}, +and your Pascal program in \file{fibo.pp}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Linking your program to a library +\section{Linking your program to a library} +\label{se:LinkOut} +To link your program to a library, the procedure depends on how you declared +the external procedure. If you used thediffers a little from the +procedure when you link in an object file. although the declaration step +remains the same (see \ref{se:ExternalDeclaration} on how to do that). + +In case you used the follwing syntax to declare your procedure: +\begin{verbatim} +Procedure ProcName (Args : TPRocArgs); external 'Name'; +\end{verbatim} +You don't need to take additional steps to link your file in, the compiler +will do all that is needed for you. + +In case you used +\begin{verbatim} +Procedure ProcName (Args : TPRocArgs); external; +\end{verbatim} +Or the older method +\begin{verbatim} +Procedure ProcName (Args : TPRocArgs); [ C ]; +\end{verbatim} +You still need to explicity link to the library. This can be done in 2 ways: +\begin{enumerate} +\item You can tell the compiler in the source file what library to link to +using the \var{\{\$LinkLib 'Name'} directive: +\begin{verbatim} +{$LinkLib 'gpm'} +\end{verbatim} +This will link to the \file{gpm} library. On \linux systems, you needn't +specify the extension or 'lib' prefix of the library. The compiler takes +care of that. On \dos or \windows systems, you need to specify the full +name. +\item You can also tell the compiler on the command-line to link in a +library: The \var{-k} option can be used for that. For example +\begin{verbatim} +ppc386 -k'-lgpm' myprog.pp +\end{verbatim} +Is equivalent to the above method, and tells the linker to link to the +\file{gpm} library. +\end{enumerate} + +As an example; consider the following program : +\begin{verbatim} +program printlength; + +{ Declaration for the standard C function strlen } +Function strlen (P : pchar) : longint; cdecl;external; + +begin + Writeln (strlen('Programming is easy !')); +end. +\end{verbatim} +This program can be compiled with : +\begin{verbatim} +pp -k'-lc' prlen.pp +\end{verbatim} +Supposing, of course, that the program source resides in \file{prlen.pp}. + +You cannot use procedures or functions that have a variable number of +arguments in C. Pascal doesn't support this feature of C. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Making a shared library +\section{Making a shared library} +\label{se:SharedLib} +If you want to make your procedures and functions available to C +programmers, you can do this very easily. All you need to do is declare the +functions and procedures that you want to make available as \var{Export}, as +follows: +\begin{verbatim} +Procedure ExportedProcedure ; export; +\end{verbatim} +This tells the compiler that it shouldn't clear the stack upon exiting the +procedure (see \sees{Calling}), thus enabling a C program to call your +function. It also means that your Pascal program can't call this function, +since it will be using the C calling mechanism. + +{\em Remark :} You can only declare a function as exported in the +\var{Implementation} section of a unit. This function may {\em not} appear +in the interface part of a unit. This is logical, since a Pascal routine +cannot call an exported function, anyway. + +However, the generated object file will not contain the name of the function +as you declared it. The \fpk compiler ''mangles'' the name you give your +function. It makes the name all-uppercase, and adds the types of all +parameters to it. For \fpk units, this doesn't matter, since the \file{.ppu} +unit file contains all information to map your function declaration onto the +mangled name in the object file. For a C programmer, who has no access to +the \var{.ppu} file, this is not very convenient. That is why \fpk +has the \var{Alias} modifier. The \var{Alias} modifier allows you to specify +another name (a nickname) for your function or procedure. + +The prototype for an aliased function or procedure is as follows : +\begin{verbatim} +Procedure AliasedProc; [ Alias : 'AliasName']; +\end{verbatim} +The procedure \var{AliasedProc} will also be known as \var{AliasName}. Take +care, the name you specify is case sensitive (as C is). + +Of course, you want to combine these two features of \fpk, to export a +function under a reasonable name; If you want to do that, you must first +specify that the function is to be exported, and then only declare an alias: +\begin{verbatim} +Procedure ExportToCProc; Export; [Alias : 'procname']; +\end{verbatim} +After that, any C program will be able to use your procedure or function. + +{\em Remark: } +If you use in your unit functions that are in other units, or +system functions, then the C program will need to link in the object files +from the units too. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Objects +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Objects} +\label{ch:Objects} +In this short chapter we give some technical things about objects. For +instructions on how to use and declare objects, see \refref. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Constructor and Destructor calls. +\section{Constructor and Destructor calls} +\label{se:ConsDest} +When using objects that need virtual methods, the compiler uses two help +procedures that are in the run-time library. They are called +\var{Help\_Destructor} and \var{Help\_Constructor}, and they are written in +assebly language. They are used to allocate the necessary memory if needed, +and to insert the Virtual Method Table (VMT) pointer in the newly allocated +object. + +When the compiler encounters a call to an object's constructor, +it sets up the stack frame for the call, and inserts a call to the +\var{Help\_Constructor} +procedure before issuing the call to the real constuctor. +The helper procedure allocates the needed memory (if needed) and inserts the +VMT pointer in the object. After that, the real constructor is called. + +A call to \var{Help\_Destructor} is inserted in every destructor declaration, +just before the destructor's exit sequence. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% memory storage of Objects +\section{Memory storage of objects} +\label{se:ObjMemory} +Objects are stored in memory just as ordinary records with an extra field : +a pointer to the Virtual Method Table (VMT). This field is stored first, and +all fields in the object are stored in the order they are declared. +This field is initialized by the call to the object's \var{Constructor} method. + +If the object you defined has no virtual methods, then a \var{nil} is stored +in the VMT pointer. This ensures that the size of objects is equal, whether +they have virtual methods ore not. + +The memory allocated looks as in \seet{ObjMem}. +\begin{FPKltable}{ll}{Object memory layout}{ObjMem} \hline +Offset & What \\ \hline ++0 & Pointer to VMT. \\ ++4 & Data. All fields in the order the've been declared. \\ +... & \\ +\hline +\end{FPKltable} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The virtual method table. +\section{The Virtual Method Table} +\label{se:VMT} +The Virtual Method Table (VMT) for each object type consists of 2 check +fields (containing the size of the data), a pointer to the object's anchestor's +VMT (\var{Nil} if there is no anchestor), and then the pointers to all virtual +methods. The VMT layout is illustrated in \seet{VMTMem}. + +The VMT is constructed by the compiler. Every instance of an object receives +a pointer to its VMT. + +\begin{FPKltable}{ll}{Virtual Method Table memory layout}{VMTMem} \hline +Offset & What \\ \hline ++0 & Size of object type data \\ ++4 & Minus the size of object type data. Enables determining of valid VMT +pointers. \\ ++8 & Pointer to ancestor VMT, \var{Nil} if no ancestor available.\\ ++12 & Pointers to the virtual methods. \\ +... & \\ +\hline +\end{FPKltable} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Generated code +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Generated code} +\label{ch:GenCode} +The \fpk compiler relies on the assembler to make object files. It generates +just the assembly language file. In the following two sections, we discuss +what is generated when you compile a unit or a program. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Units +\section{Units} +\label{se:Units} +When you compile a unit, the \fpk compiler generates 2 files : +\begin{enumerate} +\item A unit description file (with extension \file{.ppu}). +\item An assembly language file (with extension \file{.s}). +\end{enumerate} +The assembly language file contains the actual source code for the +statements in your unit, and the necessary memory allocations for any +variables you use in your unit. This file is converted by the assembler to +an object file (with extension \file{.o}) which can then be linked to other +units and your program, to form an executable. + +By default (compiler version 0.9.4 and up), the assembly file is removed +after it has been compiled. Only in the case of the \var{-s} command-line +option, the assembly file must be left on disk, so the assembler can be +called later. + +The unit file contains all the information the compiler needs to use the +unit: +\begin{enumerate} +\item Other used units, both in interface and implementation. +\item Types and variables from the interface section of the unit. +\item Function declarations from the interface section of the unit. +\item Some debugging information, when compiled with debugging. +\item A date and time stamp. +\end{enumerate} +Macros, symbols and compiler directives are {\em not} saved to the unit +description file. Aliases for functions are also not written to this file, +which is logical, since they cannot appear in the interface section of a +unit. + +The detailed contents and structure of this file are described in the first +appendix. You can examine a unit description file using the \file{dumpppu} +program, which shows the contents of the file. + +If you want to distribute a unit without source code, you must provide both +the unit description file and the object file. + +You can also provide a C header file to go with the object file. In that +case, your unit can be used by someone who wishes to write his programs in +C. However, you must make this header file yourself since the \fpk compiler +doesn't make one for you. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Programs +\section{Programs} +\label{se:Programs} + +When you compile a program, the compiler produces again 2 files : +\begin{enumerate} +\item An assembly language file containing the statements of your program, +and memory allocations for all used variables. +\item A linker response file. This file contains a list of object files the +linker must link together. +\end{enumerate} +The link response file is, by default, removed from the disk. Only when you +specify the \var{-s} command-line option or when linking fails, then the ile +is left on the disk. It is named \file{link.res}. + +The assembly language file is converted to an object file by the assembler, +and then linked together with the rest of the units and a program header, to +form your final program. + +The program header file is a small assembly program which provides the entry +point for the program. This is where the execution of your program starts, +so it depends on the operating system, because operating systems pass +parameters to executables in wildly different ways. + +It's name is \file{prt0.o}, and the +source file resides in \file{prt0.s} or some variant of this name. It +usually resided where the system unit source for your system resides. +It's main function is to save the environment and command-line arguments, +set up the stack. Then it calls the main program. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% MMX Support +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{MMX support} +\label{ch:MMXSupport} + +\section{What is it about ?} +\label{se:WhatisMMXabout} +\fpk supports the new MMX (Multi-Media extensions) +instructions of Intel processors. The idea of MMX is to +process multiple data with one instruction, for example the processor +can add simultaneously 4 words. To implement this efficiently, the +Pascal language needs to be extended. So Free Pascal allows +to add for example two \var{array[0..3] of word}, +if MMX support is switched on. The operation is done +by the \var{MMX} unit and allows people without assembler knowledge to take +advantage of the MMX extensions. + +Here is an example: +\begin{verbatim} +uses + MMX; { include some predefined data types } + +const + { tmmxword = array[0..3] of word;, declared by unit MMX } + w1 : tmmxword = (111,123,432,4356); + w2 : tmmxword = (4213,63456,756,4); + +var + w3 : tmmxword; + l : longint; + +begin + if is_mmx_cpu then { is_mmx_cpu is exported from unit mmx } + begin +{$mmx+} { turn mmx on } + w3:=w1+w2; +{$mmx-} + end + else + begin + for i:=0 to 3 do + w3[i]:=w1[i]+w2[i]; + end; +end. +\end{verbatim} + +\section{Saturation support} +\label{se:SaturationSupport} + +One important point of MMX is the support of saturated operations. +If a operation would cause an overflow, the value stays at the +highest or lowest possible value for the data type: +If you use byte values you get normally 250+12=6. This is very +annoying when doing color manipulations or changing audio samples, +when you have to do a word add and check if the value is greater than +255. The solution is saturation: 250+12 gives 255. +Saturated operations are supported by the \var{MMX} unit. If you +want to use them, you have simple turn the switch saturation on: +\var{\$saturation+} + +Here is an example: +\begin{verbatim} +\end{verbatim} + +\section{Restrictions of MMX support} +\label{se:MMXrestrictions} + +In the beginning of 1997 the MMX instructions were introduced in the +Pentium processors, so multitasking systems wouldn't save the +newly introduced MMX registers. To work around that problem, Intel +mapped the MMX registers to the FPU register. + +The consequence is that +you can't mix MMX and floating point operations. After using +MMX operations and before using floating point operations, you +have to call the routine \var{EMMS} of the \var{MMX} unit. +This routine restores the FPU registers. + +\em{Careful:} The compiler doesn't warn, if you mix floating point and +MMX operations, so be careful. + +The MMX instructions are optimized for multi media (what else?). +So it isn't possible to perform each operation, some opertions +give a type mismatch, see section \ref {se:SupportedMMX} for the supported +MMX operations + +An important restriction is that MMX operations aren't range or overflow +checked, even when you turn range and overflow checking on. This is due to +the nature of MMX operations. + +The \var{MMX} unit must be always used when doing MMX operations +because the exit code of this unit clears the MMX unit. If it wouldn't do +that, other program will crash. A consequence of this is that you can't use +MMX operations in the exit code of your units or programs, since they would +interfere with the exit code of the \var{MMX} unit. The compiler can't +check this, so you are responsible for this ! + +\section{Supported MMX operations} +\label{se:SupportedMMX} + + + +\section{Optimizing MMX support} +\label{se:OptimizingMMX} +Here are some helpful hints to get optimal performance: +\begin{itemize} +\item The \var{EMMS} call takes a lot of time, so try to seperate floating +point and MMX operations. +\item Use MMX only in low level routines because the compiler + saves all used MMX registers when calling a subroutine. +\item The NOT-operator isn't supported natively by MMX, so the + compiler has to generate a workaround and this operation + is inefficient. +\item Simple assignements of floating point numbers don't access + floating point registers, so you need no call to the \var{EMMS} + procedure. Only when doing arithmetic, you need to call the \var{EMMS} +procedure. +\end{itemize} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Memory issues +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Memory issues} +\label{ch:Memory} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The 32-bit model +\section{The 32-bit model.} +\label{se:ThirtytwoBit} +The \fpk Pascal compiler issues 32-bit code. This has several consequences: +\begin{itemize} +\item You need a i386 or higher processor to run the generated code. The +compiler functions on a 286 when you compile it using Turbo Pascal, +but the generated programs cannot be assembled or executed. +\item You don't need to bother with segment selectors. Memory can be +addressed using a single 32-bit pointer. +The amount of memory is limited only by the available amount of (virtual) +memory on your machine. +\item The structures you define are unlimited in size. Arrays can be as long +as you want. You can request memory blocks from any size. +\end{itemize} + +The fact that 32-bit code is used, means that some of the older Turbo Pascal +constructs and functions are obsolete. The following is a list of functions +which shouldn't be used anymore: +\begin{description} +\item [Seg()] : Returned the segment of a memory address. Since segments have +no more meaning, zero is returned in the \fpk run-time library implementation of +\var{Seg}. +\item [Ofs()] : Returned the offset of a memory address. Since segments have +no more meaning, the complete address is returned in the \fpk implementation +of this function. This has as a consequence that the return type is +\var{Longint} instead of \var{Word}. +\item [Cseg(), Dseg()] : Returned, respectively, the code and data segments +of your program. This returns zero in the \fpk implementation of the +system unit, since both code and data are in the same memory space. +\item [Ptr] accepted a segment and offset from an address, and would return +a pointer to this address. This has been changed in the run-time library. +Standard it returns now simply the offset. If you want to retain the old +functionality, you can recompile the run-time library with the +\var{DoMapping} symbol defined. This will restore the Turbo Pascal +behaviour. +\item [memw and mem] these arrays gave access to the \dos memory. \fpk +supports them, but they are mapped onto 32-bit flat memory space. +\end{description} + +You shouldn't use these functions, since they are very non-portable, they're +specific to \dos and the ix86 processor. The \fpk compiler is designed to be +portable to other platforms, so you should keep your code as portable as +possible, and not system specific. That is, unless you're writing some driver +units, of course. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The stack +\section{The stack} +\label{se:Stack} +The stack is used to pass parameters to procedures or functions, +to store local variables, and, in some cases, to return function +results. + +When a function or procedure is called, then the following is done by the +compiler : +\begin{enumerate} +\item If there are any parameters to be passed to the procedure, they are +pushed from right to left on the stack. +\item If a function is called that returns a variable of type \var{String}, +\var{Set}, \var{Record}, \var{Object} or \var{Array}, then an address to +store the function result in, is pushed on the stack. +\item If the called procedure or function is an object method, then the +pointer to \var{self} is pushed on the stack. +\item If the procedure or function is nested in another function or +procedure, then the frame pointer of the parent procedure is pushed on the +stack. +\item The return address is pushed on the stack (by the \var{Call} +instruction). +\end{enumerate} + +The resulting stack frame upon entering looks as in \seet{StackFrame}. +\begin{FPKltable}{llc}{Stack frame when calling a procedure}{StackFrame} +\hline +Offset & What is stored & Optional ? \\ \hline ++x & parameters & Yes \\ ++12 & function result & Yes \\ ++8 & self & Yes \\ ++4 & Frame pointer of parent procedure & Yes \\ ++0 & Return address & No\\ \hline +\end{FPKltable} + +The stack is cleared with the \var{ret} I386 instruction, meaning that the +size of all pushed parameters is limited to 64K. + +The stack size is unlimited for all supported platforms. On the \var{GO32V2} +platform, the minimum guaranteed stack is 128Kb, but this can be set with +the \var{-Ctxxx} compiler switch. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% The Heap +\section{The heap} +\label{se:Heap} +The heap is used to store all dynamic variables, and to store class +instances. The interface to the heap is the same as in Turbo Pascal, +although the effects are maybe not the same. On top of that, the \fpk +run-time library has some extra possibilities, not available in Turbo +Pascal. These extra possibilities are explained in the next subsections. + +% The heap grows +\subsection{The heap grows} +\fpk supports the \var{HeapEerror} procedural variable. If this variable is +non-nil, then it is called in case you try to allocate memory, and the heap +is full. By default, \var{HeapError} points to the \var{GrowHeap} function, +which tries to increase the heap. + +The growheap function issues a system call to try to increase the size of the +memory available to your program. It first tries to increase memory in a 1 Mb. +chunk. If this fails, it tries to increase the heap by the amount you +requested from the heap. + +If the call to \var{GrowHeap} has failed, then a run-time error is generated, +or nil is returned, depending on the \var{GrowHeap} result. + +If the call to \var{GrowHeap} was successful, then the needed memory will be +allocated. + +% Using Blocks +\subsection{Using Blocks} +If you need to allocate a lot of small block for a small period, then you +may want to recompile the run-time library with the \var{USEBLOCKS} symbol +defined. If it is recompiled, then the heap management is done in a +different way. + +The run-time library keeps a linked list of allocated blocks with size +up to 256 bytes\footnote{The size can be set using the \var{max\_size} +constant in the \file{heap.inc} source file.}. By default, it keeps 32 of +these lists\footnote{The actual size is \var{max\_size div 8}.}. + +When a piece of memory in a block is deallocated, the heap manager doesn't +really deallocate the occupied memory. The block is simply put in the linked +list corresponding to its size. + +When you then again request a block of memory, the manager checks in the +list if there is a non-allocated block which fits the size you need (rounded +to 8 bytes). If so, the block is used to allocate the memory you requested. + +This method of allocating works faster if the heap is very fragmented, and +you allocate a lot of small memory chunks. + +Since it is invisible to the program, this provides an easy way of improving +the performance of the heap manager. + +% The splitheap +\subsection{Using the split heap} +{\em Remark : The split heap is still somewhat buggy. Use at your own risk +for the moment.} + +The split heap can be used to quickly release a lot of blocks you alloated +previously. + +Suppose that in a part of your program, you allocate a lot of memory chunks +on the heap. Suppose that you know that you'll release all this memory when +this particular part of you program is finished. + +In Turbo Pascal, you could foresee this, and mark the position of the heap +(using the \var{Mark} function) when entering this particular part of your +program, and release the occupied memory in one call with the \var{Release} +call. + +For most purposes, this works very good. But sometimes, you may need to +allocate something on the heap that you {\em don't} want deallocated when you +release the allocated memory. That is where the split heap comes in. + +When you split the heap, the heap manager keeps 2 heaps: the base heap (the +normal heap), and the temporary heap. After the call to split the heap, +memory is allocated from the temporary heap. When you're finished using all +this memory, you unsplit the heap. This clears all the memory on the split +heap with one call. After that, memory will be allocated from the base heap +again. + +So far, nothing special, nothing that can't be done with calls to \var{mark} +and \var{release}. Suppose now that you have split the heap, and that you've +come to a point where you need to allocate memory that is to stay allocated +after you unsplit the heap again. At this point, mark and release are of no +use. But when using the split heap, you can tell the heap manager to +--temporarily-- use the base heap again to allocate memory. +When you've allocated the needed memory, you can tell the heap manager that +it should start using the temporary heap again. +When you're finished using the temporary heap, you release it, and the +memory you allocated on the base heap will still be allocated. + +To use the split-heap, you must recompile the run-time library with the \var{TempHeap} +symbol defined. +This means that the following functions are available : +\begin{verbatim} + procedure Split_Heap; + procedure Switch_To_Base_Heap; + procedure Switch_To_Temp_Heap; + procedure Switch_Heap; + procedure ReleaseTempHeap; + procedure GetempMem(var p : pointer;size : longint); +\end{verbatim} +\var{split\_heap} is used to split the heap. It cannot be called two times +in a row, without a call to \var{releasetempheap}. \var{Releasetempheap} +completely releases the memory used by the temporary heap. +Switching temporarily back to the base heap can be done using the +\var{switch\_to\_base\_heap} call, and returning to the temporary heap is done +using the \var{switch\_to\_temp\_heap} call. Switching from one to the other +without knowing on which one your are right now, can be done using the +\var{switch\_heap} call, which will split the heap first if needed. + +A call to \var{GetTempMem} will allocate a memory block on the temporary +heap, whatever the current heap is. The current heap after this call will be +the temporary heap. + +Typically, what will appear in your code is the following sequence : +\begin{verbatim} +Split_Heap +... +{ Memory allocation } +... +{ !! non-volatile memory needed !!} +Switch_To_Base_Heap; +getmem (P,size); +Switch_To_Temp_Heap; +... +{Memory allocation} +... +ReleaseTempHeap; +{All allocated memory is now freed, except for the memory pointed to by 'P' } +... +\end{verbatim} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Appendices +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\appendix + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Appendix A +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Anatomy of a unit file} +\label{ch:AppA} +A unit file consists of basically five parts: +\begin{enumerate} +\item A unit header. +\item A file references part. This contains the references to used units +and sources with name, checksum and time stamps. +\item A definition part. Contains all type and procedure definitions. +\item A Symbol part. Contains all symbol names and references to their +definitions. +\item A list of units that are in the implementation part. +\end{enumerate} + +The header consists of a sequence of 20 bytes, together they give some +information about the unit file, the compiler version that was used to +generate the unit file, etc. The complete layout can be found in +\seet{UnitHeader}. The header is generated by the compiler, and changes only +when the compiler changes. The current and up-to-date header definition can +be found in the \file{files.pas} source file of the compiler. Look in this +file for the \var{unitheader} constant declaration. +\begin{FPKltable}{ll}{Unit header structure.}{UnitHeader} \hline +Byte & What is stored \\ \hline +0..3 & The letters 'PPU' in upper case. This acts as a check. \\ +4..6 & The unit format as a 3 letter sequence : e.g. '0','1,'2' for format +12. \\ +7,8 & The compiler version and release numbers as bytes. \\ +9 & The target OS number. \\ +10 & Unit flags.\\ +11..14 & Checksum (as a longint). \\ +15,16 & unused (equal to 255). \\ +17..20 & Marks start of unit file. \\ \hline +\end{FPKltable} +After the header, in the second part, first the list of all source files for +the unit is written. Each name is written as a direct copy of the string in +memory, i.e. a length bytes, and then all characters of the string. This +list includes any file that was included in the unit source with the +\var{\{\$i file\}} directive. The list is terminated with a \var{\$ff} byte +marker. +After this, the list of units in the \var{uses} clause is written, +together with their checksums. The file is written as a string, the checksum +as a longint (i.e. four bytes). Again this list is terminated with a +\var{\$ff} byte marker. + +After that, in the third part, the definitions of all types, variables, +constants, procedures and functions are written to the unit file. + +They are written in the following manner: First a byte is written, which +determines the kind of definition that follows. then follows, as a series of +bytes, a type-dependent description of the definition. The exact byte order +for each type can be found in \seet{DefDef} + +\begin{FPKltable}{lccl}{Description of definition fields}{DefDef} \\hline +Type & Start byte & Size & Stored fields \\ \hline\hline +Pointer & 3 & 4 & Reference to the type pointer points to. \\ \hline +Base type & 2 & 9 & +\begin{tabular}[t]{l} +1 byte to indicate base type. \\ +4-byte start range \\ +4-byte end range \\ +\end{tabular}\\ \hline +Array type &5 & 16 & +\begin{tabular}[t]{l} +4-byte reference to element type. \\ +4-byte reference to range type.\\ +4-byte start range (longint) \\ +4-byte end range (longint)\\ +\end{tabular} \\ \hline +Procedure & 6 & ? & +\begin{tabular}[t]{l} +4-byte reference to the return type definition. \\ +2 byte Word containing modifiers. \\ +2 byte Word containing number of parameters. \\ +5 bytes per parameter.\\ +1 byte : used registers. \\ +String containing the mangled name. \\ +8 bytes. +\end{tabular} +\\ \hline +Procedural type & 21 & ? & +\begin{tabular}[t]{l} +4-byte reference to the return type definition. \\ +2 byte Word containing modifiers. \\ +2 byte Word containing number of parameters. \\ +5 bytes per parameter. \\ +\end{tabular} +\\ \hline +String & 9 & 1 & 1 byte containing the length of the string. \\ +Record & 15 & variable & +\begin{tabular}[t]{l} +Longint indicating record length \\ +list of fields, to be read as unit in itself. \\ +\var{\$ff} end marker. +\end{tabular} \\ \hline +Class & 18 & variable & +\begin{tabular}[t]{l} +Longint indicating data length \\ +String with mangled name of class.\\ +4 byte reference to ancestor class.\\ +list of fields, to be read as unit in itself. \\ +\var{\$ff} end marker. +\end{tabular} \\ \hline +file & 16 & 1(+4) & +\begin{tabular}[t]{l} +1 byte for type of file. \\ +4-byte reference to type of typed file. +\end{tabular}\\ \hline +Enumeration & 19 & 4 & Biggest element. \\ \hline +set & 20 & 5 & +\begin{tabular}[t]{l} +4-byte reference to set element type. \\ +1 byte flag. +\end{tabular} \\ \hline \hline +\end{FPKltable} +This list of definitions is again terminated with a \var{\$ff} byte marker. + +After that, a list of symbols is given, together with a reference to a +definition. This represents the names of the declarations, and the +definition they refer to. + +A reference consists of 2 words : the first word indicates the unit number +(as it appears in the uses clause), and the second word is the number of the +definition in that unit. A \var{nil} reference is stored as \var{\$ffffffff}. + +After this follows again a \var{\$ff} byte terminated list of filenames: The +names of the units in the \var{uses} clause of the implementation section. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Appendix B +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{List of compiler source files} +\label{ch:AppB} +What follows is a list of all compiler files, with a short description +of what they contain. If you're looking for something in the compiler, this +list may give you a hint on where to find it. + +The first list is a list of processor dependent files. +\begin{description} +\item [aasm.pas] This unit defines some abstract assembler objects and +routines. It is used by the processor-specific assembly routines. +\item [alpha.pas, i386.pas, m68k.pas] +These units describe a processor, its registers, flags etc. +The basis for every generated instruction. Currently the DEC alpha, Intel +386 or higher and Motorola 68000 processors are supported. +\item [tgen68k.pas, tgeni386.pas] +These units export help functions for the code generator, which are +processor specific, they form a buffer between the code generator and the +machine-specific stuff. +\item [cg68k.pas, cgi386.pas, cgi3862.pas] These units contain the code +generators for the different processor types. For the I386 there are 2 +files. +\item [cga68k.pas cgai386.pas] +These units contain frequently-used helper functions for the +processor-specific code generators. +\item [aopt386.pas] +These units contain the code optimizers for the different processor-types. +\item [asmalpha.pas] +This unit defines some DEC alpha assembly constructs. +\item [attasmi3.pas, gasasm6.pas, intasmi3.pas] +These units define processor-specific assembly output classes. +\item [opts386.pas, opts68k.pas] +These units process command-line options that are processor specific. +\item [radi386.pas rai386.pas ratti386.pas] +These units process inline assembly in different styles (AT\&T style, Intel +style, and direct style) for the Intel 386 processor. +\item [rasm386.pas] +This unit provides some helper routines for the assembly readers. +\end{description} + +The second list is a list with processor-independent files. +\begin{description} +\item [catch.pas] +This is a \linux specific call. It intercepts a segmentation fault, and lets +the compiler exit gracefully. +\item [cobjects.pas] +This unit provides some basic objects for the compiler: buffered files, +linked lists, string containers, etc. +\item [compiler.pas] +This unit contains the actual compile function. +\item [errors.pas] +This unit takes care of error-handling: displaying of error messages, +reading of error-definitions etc. +\item [files.pas] +This unit contains file management routines, such as finding of files etc. +It is highly OS dependent. +\item [gdb.pas] +This unit implements the debugging information generation for the \gnu +\var{GDB} debugger. +\item [globals.pas] +This unit defines some help routines that are used throughout the entire +compiler, and it does some initializations. +\item [hcodegen.pas] +This unit contains processor-independent helper routines for the code +generator. +\item [options.pas] +This unit processes the processor-independent command-line options. +\item [scanner.pas] +This unit contains the scanner routines. Here the input file is read and +split in tokens. +\item [parser.pas, pass\_1.pas] +These units contain the actual Pascal parser. +\item [pp.pas] +This is the main program. It does some initializations and sets the ball +rolling. +\item [symtable.pas] +This unit contains the code that keeps the symbol tables for the parser. It +also contains the code to read a unit file. +\item [systems.pas] +This unit defines the different operating systems: names, specifications of +file systems, places where to look for things etc. +\item [sysutils.pas] +This unit keeps routines for exception handling. +\item [tree.pas] +The main structure for the code generator is a tree of operators and operands, +and this unit defines the tree structure. +\item [types.pas] +This unit contains some helper routines for handling of different Pascal +types. +\item [verbose.pas] +This unit provides the verbosity support. All messages from the compiler are +put on screen with this unit. +\end{description} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Appendix C +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Compiler limits} +\label{ch:AppC} +Although many of the restrictions imposed by the MS-DOS system are removed +by use of an extender, or use of another operating system, there still are +some limitations to the compiler: +\begin{enumerate} +\item String constants are limited to 128 characters. All other characters +are simply dropped from the definition. +\item The length of generated unit files is limited to 65K for the +real-mode compiler, and to 1Mb for the 32-bit compiler. This limit can be +changed by changing the \var{bytearray1} type in \file{cobjects.pas} +\item Procedure or Function definitions can be nested to a level of 32. +\item Maximally 255 units can be used in a program when using the real-mode +compiler. When using the 32-bit compiler, the limit is set to 1024. You can +change this by redefining the \var{maxunits} constant in the +\file{files.pas} compiler source file. +\item Procedures or functions accept parameters with a total size up to +\var{\$ffff} bytes. This limit is due to the \var{RET} instruction of the I386 +processor. If the calls were made using the C convention this limit would +disappear. +\end{enumerate} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Appendix D +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Optimizing techniques used in the compiler.} +Here follows a listing of the opimizing techniques used in the compiler: +\begin{enumerate} +\item When optimizing for a specific Processor (\var{-O3, -O4, -O5 -O6}, +the following is done: +\begin{itemize} +\item In \var{case} statements, a check is done whether a jump table +or a sequence of conditional jumps should be used for optimal performance. +\item Determines a number of strategies when doing peephole optimization: +\var{movzbl (\%ebp), \%eax} on PentiumPro and PII systems will be changed +into \var{xorl \%eax,\%eax; movb (\%ebp),\%al } for lesser systems. +\end{itemize} +\item When optimizing for speed (\var{-OG}) or size (\var{-Og}), a choice is +made between using shorter instructions (for size) such as \var{enter \$4}, +or longer instructions \var{subl \$4,\%esp} for speed. When smaller size is +requested, things aren't aligned on 4-byte boundaries. When speed is +requested, things are aligned on 4-byte boundaries as much as possible. +\item Simple optimization (\var{-Oa}) makes sure the peephole optimizer is +used. +\item Maximum optimization (\var{-Ox}) avoid creation of stack frames if +they aren't required, and unnecessary loading of registers is avoided as +much as possible. (buggy at the moment (version 0.99.0). +\item For the future, a reloading optimizer is planned. +\end{enumerate} +\end{document} diff --git a/docs/progpdf.tex b/docs/progpdf.tex new file mode 100644 index 0000000000..378535e8c7 --- /dev/null +++ b/docs/progpdf.tex @@ -0,0 +1,22 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\pdfoutput=1 +\input{prog.tex} \ No newline at end of file diff --git a/docs/ref.tex b/docs/ref.tex new file mode 100644 index 0000000000..9bf29f3886 --- /dev/null +++ b/docs/ref.tex @@ -0,0 +1,2326 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\documentclass{report} +% +% Preamble +% +\usepackage{a4} +\usepackage{makeidx} +\usepackage{html} +\latex{\usepackage{fpk}} +\html{\input{fpk-html.tex}} +\makeindex +% +% start of document. +% +\begin{document} +\title{Free Pascal :\\ Reference guide.} +\docdescription{Reference guide for Free Pascal.} +\docversion{1.3} +\date{September 1997} +\author{Micha\"el Van Canneyt +% \\ Florian Kl\"ampfl +} +\maketitle +\tableofcontents +\newpage +\listoftables +\newpage +\section*{About this guide} +This document describes all constants, types, variables, functions and +procedures as they are declared in the system unit. + +Furthermore, it describes all pascal constructs supported by \fpk, and lists +all supported data types. It does not, however, give a detailed explanation +of the pascal language. The aim is to list which Pascal constructs are +supported, and to show where the \fpk implementation differs from the +Turbo Pascal implementation. + +Throughout this document, we will refer to functions, types and variables +with \var{typewriter} font. Functions and procedures gave their own +subsections, and for each function or procedure we have the following +topics: +\begin{description} +\item [Declaration] The exact declaration of the function. +\item [Description] What does the procedure exactly do ? +\item [Errors] What errors can occur. +\item [See Also] Cross references to other related functions/commands. +\end{description} +The cross-references come in two flavours: +\begin{itemize} +\item References to other functions in this manual. In the printed copy, a +number will appear after this reference. It refers to the page where this +function is explained. In the on-line help pages, this is a hyperlink, on +which you can click to jump to the declaration. +\item References to Unix manual pages. (For linux related things only) they +are printed in \var{typewriter} font, and the number after it is the Unix +manual section. +\end{itemize} +% +% The Pascal language +% +\chapter{Supported Pascal language constructs} +In this chapter we describe the pascal constructs supported by \fpk, as well +as the supported data types. + +This is not intended as an introduction to the Pascal language, although all +language constructs will be covered. The main goal is to explain what is +supported by \fpk, and where the Free implementation differs from the Turbo +Pascal one. +\section{Data types} +\fpk supports the same data types as Turbo Pascal, with some extensions from +Delphi. +\subsection{Integer types} +The integer types predefined in \fpk are listed in \seet{integers}. + +\begin{FPKltable}{lcr}{Predefined integer types}{integers} +Type & Range & Size in bytes \\ \hline +Byte & 0 .. 255 & 1 \\ +Shortint & -127 .. 127 & 1\\ +Integer & -32768 .. 32767 & 2 \\ +Word & 0 .. 65535 & 2 \\ +Longint & -2147483648 .. 2147483648 & 4\\ +Cardinal\footnote{The cardinal type support is buggy until version 0.9.3} & 0..4294967296 & 4 \\ \hline +\end{FPKltable} + +\fpk does automatic type conversion in expressions where different kinds of +integer types are used. + +\fpk supports hexadecimal format the same way as Turbo Pascal does. To +specify a constant value in hexadecimal format, prepend it with a dollar +sign (\var{\$}). Thus, the hexadecimal \var{\$FF} equals 255 decimal. + +In addition to the support for hexadecimal notation, \fpk also supports +binary notation. You can specify a binary number by preceding it with a +percent sign (\var{\%}). Thus, \var{255} can be specified in binary notation +as \var{\%11111111}. + +\subsection{Real types} +\fpk uses the math coprocessor (or an emulation) for al its floating-point +calculations. The native type for the coprocessor is \var{Double}. Other +than that, all Turbo Pascal real types are supported. They're listed in +\seet{Reals}. + \begin{FPKltable}{lccr}{Supported Real types}{Reals} +Type & Range & Significant digits & Size\footnote{In Turbo Pascal.} \\ \hline +Real & 2.9E-39 .. 1.7E38 & 11-12 & 6 \\ +Single & 1.5E-45 .. 3.4E38 & 7-8 & 4 \\ +Double & 5.0E-324 .. 1.7E308 & 15-16 & 8 \\ +Extended & 1.9E-4951 .. 1.1E4932 & 19-20 & 10\\ +%Comp\footnote{\var{Comp} only holds integer values.} & -2E64+1 .. 2E63-1 & 19-20 & 8 \\ +\end{FPKltable} + +Until version 0.9.1 of the compiler, all the real types are mapped to type +\var{Double}, meaning that they all have size 8. From version 0.9.3, the +\var{Extended} and \var{single} types are defined with the same suze as in +Turbo Pascal. The \seef{SizeOf} function is your friend here. + +\subsection{Character types} +\subsubsection{Char} +\fpk supports the type \var{Char}. A \var{Char} is exactly 1 byte in +size, and contains one character. + +You can specify a character constant by enclosing the character in single +quotes, as follows : 'a' or 'A' are both character constants. + +You can also specify a character by their ASCII +value, by preceding the ASCII value with the number symbol (\#). For example +specifying \var{\#65} would be the same as \var{'A'}. + +Also, the caret character (\verb+^+) can be used in combination with a letter to +specify a character with ASCII value less than 27. Thus \verb+^G+ equals +\var{\#7} (G is the seventh letter in the alphabet.) + +If you want to represent the single quote character, type it two times +successively, thus \var{''''} represents the single quote character. + +\subsubsection{Strings} + +\fpk supports the \var{String} type as it is defined in Turbo Pascal. +To declare a variable as a string, use the following declaration: +\begin{verbatim} +Var + S : String[Size]; +\end{verbatim} +This will declare \var{S} as a variable of type \var{String}, with maximum +length \var{Size}. \var{Size} can be any value from \var{1} to \var{255}. + +\fpk reserves \var{Size+1} bytes for the string \var{S}, and in the zeroeth +element of the string (\var{S[0]}) it will store the length of the variable. + +If you don't specify the size of the string, \var{255} is taken as a +default. + +To specify a constant string, you enclose the string in single-quotes, just +as a \var{Char} type, only now you can have more than one character. +Given that \var{S} is of type \var{String}, the following are valid assignments: +\begin{verbatim} +S:='This is a string.'; +S:='One'+', Two'+', Three'; +S:='This isn''t difficult !'; +S:='This is a weird character : '#145' !'; +\end{verbatim} +As you can see, the single quote character is represented by 2 single-quote +characters next to each other. Strange characters can be specified by their +ASCII value. + +The example shows also that you can add two strings. The resulting string is +just the concatenation of the first with the second string, without spaces in +between them. Strings can not be substracted, however. + +\subsubsection{PChar} + +\fpk supports the Delphi implementation of the \var{PChar} type. \var{PChar} +is defined as a pointer to a \var{Char} type, but allows additional +operations. + +The \var{PChar} type can be understood best as the Pascal equivalent of a +C-style null-terminated string, i.e. a variable of type \var{PChar} is a pointer +that points to an array of type \var{Char}, which is ended by a +null-character (\var{\#0}). + +\fpk supports initializing of \var{PChar} typed constants, or a direct +assignment. For example, the following pieces of code are equivalent: + +\begin{CodEx} +\begin{verbatim} +program one; + +var p : pchar; + +begin + P:='This is a null-terminated string.'; + writeln (P); +end. +\end{verbatim} +\end{CodEx} +Results in the same as +\begin{CodEx} +\begin{verbatim} +program two; + +const P : PChar = 'This is a null-terminated string.' + +begin + Writeln (P); +end. +\end{verbatim} +\end{CodEx} +These examples also show that it is possible to write {\em the contents} of +the string to a file of type \var{Text}. + +The \seestrings\_ unit contains procedures and functions that manipulate the +\var{PChar} type as you can do it in C. + +Since it is equivalent to a pointer to a type \var{Char} variable, it is +also possible to do the following: +\begin{CodEx} +\begin{verbatim} +Program three; + +Var S : String[30]; + P : Pchar; + +begin + S:='This is a null-terminated string.'#0; + P:=@S[1]; + writeln (P); +end. +\end{verbatim} +\end{CodEx} +This will have the same result as the previous two examples. + +You cannot add null-terminated strings as you can do with normal Pascal +strings. If you want to concatenate two \var{PChar} strings, you will need +to use the \seestrings unit. + +However, it is possible to do some pointer arithmetic. You can use the +operators \var{+} and \var{-} to do operations on \var{PChar} pointers. +In \seet{PCharMath}, \var{P} and \var{Q} are of type \var{PChar}, and +\var{I} is of type \var{Longint}. +\begin{FPKltable}{lr}{\var{PChar} pointer arithmetic}{PCharMath} +Operation & Result \\ \hline +\var{P + I} & Adds \var{I} to the address pointed to by \var{P}. \\ +\var{I + P} & Adds \var{I} to the address pointed to by \var{P}. \\ +\var{P - I} & Substracts \var{I} from the address pointed to by \var{P}. \\ +\var{P - Q} & Returns, as an integer, the distance between 2 addresses \\ + & (or the number of characters between \var{P} and \var{Q}) \\ +\hline +\end{FPKltable} + +\subsection{Booleans} +\fpk supports the \var{Boolean} type, with its two pre-defined possible +values \var{True} and \var{False}. These are the only two values that can be +assigned to a \var{Boolean} type. Of course, any expression that resolves +to a \var{boolean} value, can also be assigned to a boolean type. + +Assuming \var{B} to be of type \var{Boolean}, the following are valid +assignments: +\begin{verbatim} + B:=True; + B:=False; + B:=1<>2; { Results in B:=True } +\end{verbatim} +Boolean expressions are also used in conditions. + +{\em Remark:} In \fpk, boolean expressions are always evaluated in such a +way that when the result is known, the rest of the expression will no longer +be evaluated (Called short-cut evaluation). In the following example, the function \var{Func} will never +be called, which may have strange side-effects. +\begin{verbatim} + ... + B:=False; + A := B and Func; +\end{verbatim} +Here \var{Func} is a function which returns a \var{Boolean} type. + +\subsection{Arrays} +\fpk supports arrays as in Turbo Pascal, except that packed arrays are not +supported. + +Multi-dimensional arrays are also supported. + +\subsection{Pointers} +\fpk supports the use of pointers. A variable of the type \var{Pointer} +contains an address in memory, where the data of another variable may be +stored. + +Pointers can be typed, which means that they point to a particular kind of +data. The type of this data is known at compile time. + +Consider the following example: +\begin{CodEx} +\begin{verbatim} +Program pointers; + +type + Buffer = String[255]; + BufPtr = ^Buffer; + +Var B : Buffer; + BP : BufPtr; + PP : Pointer; + +etc.. +\end{verbatim} +\end{CodEx} +In this example, \var{BP} {\em is a pointer to} a \var{Buffer} type; while \var{B} +{\em is} a variable of type \var{Buffer}. \var{B} takes 256 bytes memory, +and \var{BP} only takes 4 bytes of memory (enough to keep an adress in +memory). + +{\em Remark:} \fpk treats pointers much the same way as C does. This means +that you can treat a pointer to some type as being an array of this type. +The pointer then points to the zeroeth element of this array. Thus the +following pointer declaration +\begin{verbatim} +Var p : ^Longint; +\end{verbatim} +Can be considered equivalent to the following array declaration: +\begin{verbatim} +Var p : array[0..Infinity] of Longint; +\end{verbatim} +The reference \verb+P^+ is then the same as \var{p[0]}. The following program +illustrates this maybe more clear: +\begin{CodEx} +\begin{verbatim} +program PointerArray; + +var i : longint; + p : ^longint; + pp : array[0..100] of longint; + +begin + for i:=0 to 100 do pp[i]:=i; { Fill array } + p:=@pp[0]; { Let p point to pp } + for i:=0 to 100 do if p[i]<>pp[i] then writeln ('Ohoh, problem !') +end. +\end{verbatim} +\end{CodEx} +\fpk doesn't support pointer arithmetic as C does, however. + +\subsection{Procedural types} +\fpk has support for procedural types, although it differs from the Turbo +Pascal implementation of them. + +The type declaration remains the same. The two following examples are valid +type declarations: +\begin{verbatim} +Type TOneArg = Procedure (Var X : integer); + TNoArg = Function : Real; + +var proc : TOneArg; + func : TNoArg; +\end{verbatim} +Given these declarations, the following assignments are valid: +\begin{verbatim} +Procedure printit (Var X : Integer); + +begin + writeln (x); +end; +... + +P:=@printit; +Func:=@Pi; +\end{verbatim} +From this example, the difference with Turbo Pascal is clear: In Turbo +Pascal it isn't necessary to use the address operator (\var{@}) +when assigning a procedural type variable, whereas in \fpk it is required. + +\subsection{Records} + +\fpk supports records. The prototype type definition of a record is: +\begin{verbatim} +Type + RecType = Record + Element1 : type1; + Element2,Element3 : type2; + ... + Elementn ; Typen; + end; +\end{verbatim} +Variant records are also supported: +\begin{verbatim} +Type + RecType = Record + Element1 : type1; + Case [PivotElmt:] Type Identifier of + Value1 : (VarElt1, Varelt2 : Vartype1); + Value2 : (VarElt3, Varelt4 : Vartype2); + end; +\end{verbatim} +The variant part must be last in the record. The optional \var{PivotElmt} +can be used to see which variant is active at a certain time. + +{\em Remark:} If you want to read a typed file with records, produced by +a Turbo Pascal program, then chances are that you will not succeed in +reading that file correctly. + +The reason for this is that by default, elements of a record are aligned at +2-byte boundaries, for performance reasons. This default behaviour can be +changed with the \var{\{\$PackRecords n\}} switch. Possible values for +\var{n} are 1, 2 and 4. This switch tells the compiler to align elements of +a record on 1,2 or 4 byte boundaries. Take a look at the following program: +\begin{CodEx} +\begin{verbatim} +Program PackRecordsDemo; + +type {$PackRecords 2} + Trec1 = Record + A : byte; + B : Word; + + end; + + {$PACKRECORDS 1} + Trec2 = Record + A : Byte; + B : Word; + end; + +begin + Writeln ('Size Trec1 : ',SizeOf(Trec1)); + Writeln ('Size Trec2 : ',SizeOf(Trec2)); +end. +\end{verbatim} +\end{CodEx} +The output of this program will be : +\begin{verbatim} +Size Trec1 : 4 +Size Trec2 : 3 +\end{verbatim} +And this is as expected. In \var{Trec1}, each of the elements \var{A} and +\var{B} takes 2 bytes of memory, and in \var{Trec1}, \var{A} takes only 1 +byte of memory. + +As from version 0.9.3 (a developers' version), \fpk supports also the +'packed record', this is a record where all the elements are byte-aligned. + +Thus the two following declarations are equivalent: +\begin{verbatim} + {$PACKRECORDS 1} + Trec2 = Record + A : Byte; + B : Word; + end; + {$PACKRECORDS 2} +\end{verbatim} +and +\begin{verbatim} + Trec2 = Packed Record + A : Byte; + B : Word; + end; +\end{verbatim} +Note the \var{\{\$PACKRECORDS 2\}} after the first declaration ! + +\subsection{Set types} + +\fpk supports the set types as in Turbo Pascal. The prototype of a set +declaration is: +\begin{verbatim} +SetType = Set of TargetType; +\end{verbatim} + +Each of the elements of \var{SetType} must be of type \var{TargetType}. +\var{TargetType} can be any ordinal type with a range between \var{0} and +\var{255}. A set can contain maximally \var{255} elements. + +The following is a valid set declaration: +\begin{verbatim} +Type Days = (Mon, Tue, Wed, Thu, Fri, Sqt, Sun); + +Var WeekDays : Set of days; +\end{verbatim} +Given this set declaration, the follwing assignment is legal: +\begin{verbatim} +WeekDays := [ Mon, Tue, Wed, Thu, Fri]; +\end{verbatim} +The operators for manipulations of sets are listed in \seet{SetOps}. +\begin{FPKltable}{lr}{Set Manipulation operators}{SetOps} +Operation & Operator \\ \hline +Union & + \\ +Difference & - \\ +Intersection & * \\ \hline +\end{FPKltable} + +You can compare two sets with the \var{<>} and \var{=} operators, but not +(yet) with the \var{<} and \var{>} operators. + +From compiler version 0.9.5, the compiler stores small sets (less than 32 +elements) in a longint, if the type range allows it. This allows for faster +processing and decreases program size. + +\subsection{Enumeration types} + +Enumeration types are supported in \fpk. On top of the Turbo Pascal +implementation, \fpk allows the following C-style extension of the +enumeration type. +\begin{verbatim} +Type + EnumType = (one, two, three, forty := 40); +\end{verbatim} +As a result, the ordinal number of \var{forty} is \var{40}, and not \var{4}, +as it would be when the \var{'= 40'} wasn't present. + +When specifying such an enumeration type, it is important to keep in mind +that you should keep initialized set elements in ascending order. The +following will produce a compiler error: +\begin{verbatim} +Type + EnumType = (one, two, three, forty := 40, thirty:=30); +\end{verbatim} +It is necessary to keep \var{forty} and \var{Thirty} in the correct order. + +{\em Remark :} You cannot use the \var{Pred} and \var{Succ} functions on +this kind of enumeration types. If you try to do that, you'll get a compiler +error. + +\section{Constants} + +Just as in Turbo Pascal, \fpk supports both normal and typed constants. +\subsection{Ordinary constants} +Ordinary constants declarations are no different from the TP implementation. +You can only declare constants of the following types: \var{Ordinal types}, +\var{Real types}, \var{Char}, and \var{String}. +The following are all valid constant declarations: +\begin{verbatim} +Const + e = 2.7182818; { Real type constant. } + a = 2; { Integer type constant. } + c = '4'; { Character type constant. } + s = 'This is a constant string'; {String type constant.} +\end{verbatim} +Assigning a value to a constant is not permitted. Thus, given the previous +declaration, the following will result in a compiler error: +\begin{verbatim} + s:='some other string'; +\end{verbatim} + +\subsection{Typed constants} +Typed constants serve to provide a program with initialized variables. +Contrary to ordinary constants, they may be assigned to at run-time. +The difference with normal variables is that their value is initialised +when the program starts, whereas normal variables must be initialised +explicitly. + +The prototype of a typed constant declaration is: +\begin{verbatim} +Const + SomeConst : SomeType = SomeValue; +\end{verbatim} +After that, the constant \var{SomeConst} will be of type \var{SomeType}, and +have initial value \var{SomeValue}. + +Given the declaration: +\begin{verbatim} +Const + S : String = 'This is a typed constant string'; +\end{verbatim} +The following is a valid assignment: +\begin{verbatim} + S:='Result : '+Func; +\end{verbatim} +Where \var{Func} is a function that returns a \var{String}. + +Typed constants also allow you to initialize arrays and records. For arrays, +the initial elements must be specified, surrounded by round brackets, and +separated by commas. The number of elements must be exactly the same as +number of elements in the declaration of the type. + +As an example: +\begin{verbatim} +Const + tt : array [1..3] of string[20] = ('ikke','gij', 'hij'); + ti : array [1..3] of longint = (1,2,3); +\end{verbatim} + +For constant records, you should specify each element of the record, in the +form \var{Field : Value}, separated by commas, and surrounded by round +brackets. + +As an example: +\begin{verbatim} +Type + Point = record + X,Y : Real + end; + +Const + Origin : Point = (X:0.0 , Y:0.0); +\end{verbatim} +The order of the fields in a constant record needs to be the same as in the type declaration, +otherwise you'll get a compile-time error. + +\section{Objects} +\fpk supports object oriented programming. In fact, part of the compiler is +written using objects. Here we present some technical questions regarding +object oriented programming in \fpk. + +\fpk supports 2 programming models for object-oriented programming. +You can choose to program object oriented using the Turbo Pascal approach, +or you can prefer the Delphi approach. + +\subsection{The Turbo Pascal approach} +In the Turbo Pascal approach, Objects should be treated as a special kind of +record. The record contains all the fields that are declared in the objects +definition, and pointers to the methods that are associated to the objects' +type. + +An object is declared just as you would declare a record; except that you +can now declare procedures and fuctions as of they were part of the record. + +Objects can ''inherit'' fields and methods from ''parent'' objects. This means +that you can use these fields and methods as if the were included in the +objects you declared as a ''child'' object. + +Furthermore, you can declare fields, procedures and functions as \var{public} +or \var{private}. By default, fields and methods are \var{public}, and are +exported outside the current unit. Fields or methods that are declared +\var{private} are only accessible in the current unit. + +The prototype declaration of an object is as follows : +\begin{verbatim} +TObj = Object [(ParentObjectType)] + [Constructor ConstructorName;] + [Destructor DestructorName;] + Field1 : Type1; + ... + Fieldn : Typen; + Method1; + Method2; + [private + PrField1 : PrType1; + ... + PrFieldn : PrTypen; + PrMethod1; + ... + PrMethodn;] + [public + PuField1 : PuType1; + .. + Pufield1 : PuTypen; + PuMethod1; + ... + PuMethodn;] + end; +\end{verbatim} +You can repeat as many \var{private} and \var{public} blocks as you want. +\var{Method}s are normal function or procedure declarations. + +As can be seen in the prototype object declaration, \fpk supports +constructors and destructors. You are responsible for calling the +destructor and constructor explicitly when using objects. + +\fpk supports also the extended syntax of the \var{New} and \var{Dispose} +procedures. In case you want to allocate a dynamic varible of an object +type, you can specify the constructor's name in the call to \var{New}. +The \var{New} is implemented as a function which returns a pointer to the +instantiated object. Given the following declarations : +\begin{verbatim} +Type + TObj = object; + Constructor init; + ... + end; + Pobj = ^TObj; + +Var PP : Pobj; +\end{verbatim} +Then the following 3 calls are equivalent : +\begin{verbatim} + pp:=new (Pobj,Init); +\end{verbatim} +and +\begin{verbatim} + new(pp,init); +\end{verbatim} +and also +\begin{verbatim} + new (pp); + pp^.init; +\end{verbatim} +In the last case, the compiler will issue a warning that you should use the +extended syntax of \var{new} and \var{dispose} to generate instances of an +object. You can ignore this warning, but it's better programming practice to +use the extended syntax to create instances of an object. + +Similarly, the \var{Dispose} procedure accepts the name of a destructor. The +destructor will then be called, before removing the object from the heap. + +In view of the compiler warning remark, the now following Delphi approach may +be considered a more natural way of object-oriented programming. + +\subsection{The Delphi approach} +In the Delphi approach to Object Oriented Programming, everything revolves +around the concept of 'Classes'. +A class can be seen as a pointer to an object, or a pointer to a record. + +The prototype declaration of a class is as follows : +\begin{verbatim} +TObj = Class [(ParentClassType)] + [Constructor ConstructorName;] + [Destructor DestructorName;] + Field1 : Type1; + ... + Fieldn : Typen; + Method1; + Method2; + [private + PrField1 : PrType1; + ... + PrFieldn : PrTypen; + PrMethod1; + ... + PrMethodn;] + [public + PuField1 : PuType1; + .. + Pufield1 : PuTypen; + PuMethod1; + ... + PuMethodn;] + end; +\end{verbatim} +You can repeat as many \var{private} and \var{public} blocks as you want. +\var{Method}s are normal function or procedure declarations. + +As you can see, the declaration of a class is almost identical to the +declaration of an object. The real difference between objects and classes +is in the way they are created; + +Classes must be created using their constructor. Remember that A class is a +pointer to an object, so when you declare a variable of some class, the +compiler just allocates a pointer, not the entire object. The constructor of +a class returns a pointer to an initialized instance of the object. + +So, to initialize an instance of some class, you do the following : +\begin{verbatim} + ClassVar:=ClassType.ConstructorName; +\end{verbatim} + +{\em Remark :} \fpk doesn't support the concept of properties yet. + +\section{Statements controlling program flow.} + +\subsection{Assignments} +In addition to the standard Pascal assignment operator (\var{:=}), \fpk +supports some c-style constructions. All available constructs are listed in +\seet{assignments}. +\begin{FPKltable}{lr}{Allowed C constructs in \fpk}{assignments} +Assignment & Result \\ \hline +a += b & Adds \var{b} to \var{a}, and stores the result in \var{a}.\\ +a -= b & Substracts \var{b} from \var{a}, and stores the result in +\var{a}. \\ +a *= b & Multiplies \var{a} with \var{b}, and stores the result in +\var{a}. \\ +a /= b & Divides \var{a} through \var{b}, and stores the result in +\var{a}. \\ \hline +\end{FPKltable} +For these connstructs to work, you should specify the \var{-Sc} +command-line switch. + +{\em Remark:} These constructions are just for typing convenience, they +don't generate different code. + +\fpk also supports typed assignments. This means that an assignment +statement has a definite type, and hence can be assigned to another +variable. The type of the assignment \var{a:=b} is the type of \var{a} +(or, in this case, of \var{b}), and this can be assigned to another +variable : \var{c:=a:=b;}. +To summarize: the construct +\begin{verbatim} + a:=b:=c; +\end{verbatim} +results in both \var{a} and \var{b} being assign the value of \var{c}, which +may be an expression. + +For this construct to be allowed, it is necessary to specify the \var{-Sa4} +switch on the command line. + +\subsection{The \var{Case} statement} +\fpk supports the \var{case} statement. Its prototype is +\begin{verbatim} +Case Pivot of + Label1 : Statement1; + Label2 : Statement2; + ... + Labeln : Statementn; +[Else + AlternativeStatement] +end; +\end{verbatim} +\var{label1} until \var{Labeln} must be known at compile-time, and can be of +the following types : enumeration types, Ordinal types (except boolean), and +chars. \var{Pivot} must also be one of these types. + +The statements \var{Statement1} etc., can be compound statements (i.e. a +\var{begin..End} block). + +{\em Remark:} Contrary to Turbo Pascal, duplicate case labels are not +allowed in \fpk, so the following code will generate an error when +compiling: + +\begin{verbatim} +Var i : integer; +... + +Case i of + 3 : DoSomething; + 1..5 : DoSomethingElse; +end; +\end{verbatim} +The compiler will generate a \var{Duplicate case label} error when compiling +this, because the 3 also appears (implicitly) in the range \var{1..5} + +{\em Remark:} In versions earlier than 0.9.7, there was an incompatibility here +with Turbo Pascal. Where in Turbo Pascal you could do the following: +\begin{verbatim} +case Pivot of + ... +Else + begin + Statement1 + Statement2 + end; +\end{verbatim} +You needed to do the following in \fpk : +\begin{verbatim} +case Pivot of + ... +Else + begin + Statement1 + Statement2 + end; +end; +\end{verbatim} +So there's an extra \var{end} keyword at the end. But from version 0.9.7 +this has been fixed. +\subsection{The \var{For..to/downto..do} statement} +\fpk supports the \var{For} loop construction. The prototypes are: +\begin{verbatim} +For Counter:=Lowerbound to Upperbound Do Statement; + +or + +For Counter:=Upperbound downto Lowerbound Do Statement; +\end{verbatim} +\var{Statement} can be a compound statement. In the first case, if +\var{Lowerbound} is larger than \var{Upperbound} then \var{Statement} will +never be executed. +\subsection{The \var{Goto} statement} +\fpk supports the \var{goto} jump statement. Its prototype is +\begin{verbatim} + +var + jumpto : label +... +Jumpto : + Statement; +... +Goto jumpto; +... +\end{verbatim} +The jump label must be defined in the same block as the \var{Goto} +statement. +To be able to use the \var{Goto} statement, you need to specify the \var{-Sg} +compiler switch. +\subsection{The \var{If..then..else} statement} +The \var{If .. then .. else..} prototype is: +\begin{verbatim} +If Expression1 Then Statement1; + +or + +If Expression2 then + Statement2 +else + Statement3; +\end{verbatim} +Be aware of the fact that the boolean expressions \var{Expression1} and +\var{Expression2} will be short-cut evaluated. (Meaning that the evaluation +will be stopped at the point where the outcome is known with certainty) + +Also, after \var{Statement2}, no semicolon (\var{;}) is alllowed. + +All statements can be compound statements. +\subsection{The \var{Repeat..until} statement} +The prototype of the \var{Repeat..until} statement is +\begin{verbatim} +Repeat + Statement1; + Statement2; +Until Expression; +\end{verbatim} +This will execute \var{Statement1} etc. until \var{Expression} evaluates to +\var{True}. Since \var{Expression} is evaluated {\em after} the execution of the +statements, they are executed at least once. + +Be aware of the fact that the boolean expressions \var{Expression1} and +\var{Expression2} will be short-cut evaluated. (Meaning that the evaluation +will be stopped at the point where the outcome is known with certainty) + +\subsection{The \var{While..do} statement} +The prototype of the \var{While..do} statement is +\begin{verbatim} +While Expression Do + Statement; +\end{verbatim} +This will execute \var{Statement} as long as \var{Expression} evaluates to +\var{True}. Since \var{Expression} is evaluated {\em before} the execution +of \var{Statement}, it is possible that \var{Statement} isn't executed at +all. + +\var{Statement} can be a compound statement. + +Be aware of the fact that the boolean expressions \var{Expression1} and +\var{Expression2} will be short-cut evaluated. (Meaning that the evaluation +will be stopped at the point where the outcome is known with certainty) + +\subsection{The \var{With} statement} +The with statement serves to access the elements of a record, without +having to specify the name of the record. Given the declaration: +\begin{verbatim} +Type Passenger = Record + Name : String[30]; + Flight : String[10]; + end; + +Var TheCustomer : Passenger; +\end{verbatim} +The following statements are completely equivalent: +\begin{verbatim} +TheCustomer.Name:='Michael'; +TheCustomer.Flight:='PS901'; +\end{verbatim} +and +\begin{verbatim} +With TheCustomer do + begin + Name:='Michael'; + Flight:='PS901'; + end; +\end{verbatim} + +\subsection{Compound statements} +Compound statements are a group of statements, separated by semicolons, +that are surrounded by the keywords \var{Begin} and \var{End}. The +Last statement doesn't need to be followed by a semicolon, although it is +allowed. + +\section{Using functions and procedures} +\fpk supports the use of functions and procedures, but with some extras: +Function overloading is supported, as well as \var{Const} parameters and +open arrays. + +{\em remark:} In the subsequent paragraph the word \var{procedure} and +\var{function} will be used interchangeably. The statements made are +valid for both. + +\subsection{Function overloading} +Function overloading simply means that you can define the same function more +than once, but each time with a different set of arguments. + +When the compiler encounters a unction call, it will look at the function +parameters to decide which od the defined function +This can be useful if you want to define the same function for different +types. For example, if the RTL, the \var{Dec} procedure is +is defined as: +\begin{verbatim} +... +Dec(Var I : longint;decrement : longint); +Dec(Var I : longint); +Dec(Var I : Byte;decrement : longint); +Dec(Var I : Byte); +... +\end{verbatim} +When the compiler encounters a call to the dec function, it wil first search +which function it should use. It therefore checks the parameters in your +function call, and looks if there is a function definition which maches the +specified parameter list. If the compiler finds such a function, a call is +inserted to that function. If no such function is found, a compiler error is +generated. + +\subsection{\var{Const} parameters} +In addition to \var{var} parameters and normal parameters (call by value, +call by reference), \fpk also supports \var{Const} parameters. You can +specify a \var{Const} parameter as follows: +\begin{verbatim} +Function Name (Const S: Type_Of_S) : ResultType +\end{verbatim} +A constant argument is passed by refenence +(i.e. the function or procedure receives a pointer to the passed , +but you are not allowed to assign to it, this will result in a compiler error. + +The main use for this is reducing the stack size, hence improving +performance. + +\subsection{Open array parameters} +\fpk supports the passing of open arrays, i.e. You can declare a procedure +with an array of unspecified length as a parameter, as in Delphi. + +The prototype declaration for open array parameters is: +\begin{verbatim} +Function Func ( ... [Var|Const] Ident : Array of Type ...) : ReturnType; + +ProcedureFunction Func (... [Var|Const] Ident : Array of Type ...); +\end{verbatim} +The \var{[Var|Const]} means that open parameters can be passed by reference +or as a constant parameter. + +In a function or procedure, you can pass open arrays only to functions which +are also declared with open arrays as parameters, {\em not} to functions or +procedures which accept arrays of fixed length. + +\section{Using assembler in your code} +\fpk supports the use of assembler in your code, but not inline +assembler. assembly functions (i.e. functions declared with the +\var{Assembler} keyword) are supported as of version 0.9.7. + +{\em Remark :} +\fpk issues AT\&T assembly language, as understood by most +unix assemblers (most notably : GNU \var{as}). +Intel assembler syntax is available as of version 0.9.8 but the Intel +support isn't complete in the sense that it is converted to AT\&T syntax, +and some constructions aren't supported by the conversion mechanism (see +\progref for more information about this). +Therefore all examples of assembly language will be given in AT\&T syntax, +as it is the 'native' assembly from \fpk. + +The following is an example of assembler inclusion in your code. +\begin{verbatim} + ... + Statements; + ... + Asm + Movl 0,%eax + ... + end; + ... + Statements; +\end{verbatim} +The assembler instructions between the \var{Asm} and \var{end} keywords will +be inserted in the assembler generated by the compiler. + +You can still use comditionals in your assembler, the compiler will +recognise it, and treat it as any other conditionals. + +Contrary to Turbo Pascal, it isn't possible (yet) to reference variables by +their names in the assembler parts of your code. + +\section{Modifiers} +\fpk doesn't support all Turbo Pascal modifiers, but +does support a number of additional modifiers. They are used mainly for assembler and +reference to C object files. + +\subsection{Public} +The \var{Public} keyword is used to declare a function globally in a unit. +This is useful if you don't want a function to be accessible from the unit +file, but you do want the function to be accessible from the object file. + +as an example: +\begin{CodEx} +\begin{verbatim} +Unit someunit; + +interface + +Function First : Real; + +Implementation + +Function First : Real; +begin + First:=0; +end; + +Function Second : Real; [Public]; + +begin + Second:=1; +end; + +end. +\end{verbatim} +\end{CodEx} +If another program or unit uses this unit, it will not be able to use the +function \var{Second}, since it isn't declared in the interface part. +However, it will be possible to access the function \var{Second} at the +assembly-language level, by using it's mangled name (\progref). + +\subsection{C} +The \var{C} modifier can be used to declare a function that resides in a +object file generated by a C compiler. It allows you to use the function in +your code, and at linking time, you must link the object file containing the +\var{C} implementation of the function or procedure. + +As an example: +\begin{CodEx} +\begin{verbatim} +program CmodDemo; + +Const P : Pchar = 'This is fun !'; + +Function strlen (P : Pchar) : Longint; [ C ]; + +begin + Writeln ('Length of (',p,') : ',strlen(p)) +end. +\end{verbatim} +\end{CodEx} +When compiling this, and linking to the C-library, you will be able to call +the \var{strlen} function throughout your program. + +{\em Remark} The parameters in our declaration of the \var{C} function should +match exactly the ones in the declaration in \var{C}. S +ince \var{C} is case sensitive, this means also that the name of the +function must be exactly the same. + +\subsection{Export} +Sometimes you must provide a callback function for a C library, or you want +your routines to be callable from a C program. Since \fpk and C use +different calling schemes for functions and procedures\footnote{More +techically: In C the calling procedure must clear the stack. In \fpk, the +subroutine clears the stack.}, the compiler must be told to generate code +that can be called from a C routine. This is where the \var{Export} modifier +comes in. Contrary to the other modifiers, it must be specified separately, +as follows: +\begin{verbatim} +function DoSquare (X : longint) : longint; export; + +begin +... +end; +\end{verbatim} +The square brackets around the modifier are not allowed in this case. + +{\em Remark:} You cannot call an exported function from within \fpk programs. +If you try to do so, the compiler will complain when compiling your source +code. + +If you do want to call an exported procedure from pascal, you must use a +dummy function: +\begin{verbatim} +Procedure RealDoSomething; +begin +... +end; + +Procedure DoSomething; export; + +begin + RealDoSomething; +end; +\end{verbatim} +In this example, from your \fpk code, you can call the \var{RealDoSomething} +procedure. If someone wants to link to your code from a C program, he can +call the \var{DoSomething} procedure. Both calls will have the same effect. + +{\em Remark:} +as of version 0.9.8, \fpk supports the Delphi \var{cdecl} modifier. +This modifier works in the same way as the \var{export} modifier. + +More information about these modifiers can be found in the \progref, in the +section on the calling mechanism and the chapter on linking. + +\subsection{StdCall} +As of version 0.9.8, \fpk supports the Delphi \var{stdcall} modifier. +This modifier does actually nothing, since the \fpk compiler by default +pushes parameters from right to left on the stack, which is what the +modifier does under Delphi (which pushes parameters on the stack from left to +right). + +More information about this modifier can be found in the \progref, in the +section on the calling mechanism and the chapter on linking. + +\subsection{Alias} +The \var{Alias} modifier allows you to specify a different name for a +procedure or function. This is mostly useful for referring to this procedure +from assembly language constructs. As an example, consider the following +program: + +\begin{CodEx} +\begin{verbatim} +Program Aliases; + +Procedure Printit; [Alias : 'DOIT']; + +begin + Writeln ('In Printit (alias : "DOIT")'); +end; + +begin + asm + call DOIT + end; +end. +\end{verbatim} +\end{CodEx} +{\rm Remark:} the specified alias is inserted straight into the assembly +code, thus it is case sensitive. + +The \var{Alias} modifier, combined with the \var{Public} modifier, make a +powerful tool for making externally accessible object files. + +\subsection{[RegisterList]} +This modifier list is used to indicate the registers that are modified by an +assembler block in your code. The compiler stores certain results in the +registers. If you modify theregisters in an assembly block, the compiler +should, sometimes, be told about it. +The prototype syntax of the \var{Registerlist} modifier is: +\begin{verbatim} +asm + statements +end; ['register1','register2',...,'registern']; +\end{verbatim} +Where \var{'register'} is one of \var{'EAX',EBX',ECX','EDX'} etc. + + +\subsection{Unsupported Turbo Pascal modifiers} +The modifiers that exist in Turbo pascal, but aren't supported by \fpk, are +listed in \seet{Modifs}. +\begin{FPKltable}{lr}{Unsupported modifiers}{Modifs} +Modifier & Why not supported ? \\ \hline +Near & \fpk is a 32-bit compiler.\\ +Far & \fpk is a 32-bit compiler. \\ +External & Replaced by \var{C} modifier. \\ \hline +\end{FPKltable} + +% +% System unit reference guide. +% + +\chapter{Reference : The system unit} +The system unit contains the standard supported functions of \fpk. It is the +same for all platforms. Basically it is the same as the system unit provided +with Borland or Turbo Pascal. + +Functions are listed in alphabetical order. +Arguments to functions or procedures that are optional are put between +square brackets. + +The pre-defined constants and variables are listed in the first section. The +second section contains the supported functions and procedures. +\section{Types, Constants and Variables} +\subsection{Types} +The following integer types are defined in the System unit: +\begin{verbatim} +shortint = -128..127; +longint = $80000000..$7fffffff; +integer = -32768..32767; +byte = 0..255; +word = 0..65535; +\end{verbatim} + +The following Real types are declared: +\begin{verbatim} +double = real; +{$ifdef VER0_6} + extended = real; + single = real; +{$endif VER0_6} +\end{verbatim} + +And the following pointer types: +\begin{verbatim} + pchar = ^char; + ppchar = ^pchar; +\end{verbatim} + +\subsection{Constants} +The following constants for file-handling are defined in the system unit: +\begin{verbatim} +Const + fmclosed = $D7B0; + fminput = $D7B1; + fmoutput = $D7B2; + fminout = $D7B3; + fmappend = $D7B4; + + filemode : byte = 2; +\end{verbatim} +Further, the following general-purpose constants are also defined: +\begin{verbatim} +const + test8086 : byte = 2; { always i386 or newer } + test8087 : byte = 3; { Always 387 or higher. emulated if needed. } + erroraddr : pointer = nil; + errorcode : word = 0; + { max level in dumping on error } + max_frame_dump : word = 20; +\end{verbatim} + +\subsection{Variables} +The following variables are defined and initialized in the system unit: +\begin{verbatim} +var + output,input,stderr : text; + exitproc : pointer; + exitcode : word; + stackbottom : longint; + loweststack : longint; +\end{verbatim} +The variables \var{ExitProc}, \var{exitcode} are used in the \fpk exit +scheme. It works similarly to the on in Turbo Pascal: + +When a program halts (be it through the call of the \var{Halt} function or +\var{Exit} or through a run-time error), the exit mechanism checks the value +of \var{ExitProc}. If this one is non-\var{Nil}, it is set to \var{Nil}, and +the procedure is called. If the exit procedure exits, the value of ExitProc +is checked again. If it is non-\var{Nil} then the above steps are repeated. + +So if you want to install your exit procedure, you should save the old value +of \var{ExitProc} (may be non-\var{Nil}, since other units could have set it before +you did). In your exit procedure you then restore the value of +\var{ExitProc}, such that if it was non-\var{Nil} the exit-procedure can be +called. + +The \var{ErrorAddr} and \var{ExitCode} can be used to check for +error-conditions. If \var{ErrorAddr} is non-\var{Nil}, a run-time error has +occurred. If so, \var{ExitCode} contains the error code. If \var{ErrorAddr} is +\var{Nil}, then {ExitCode} contains the argument to \var{Halt} or 0 if the +program terminated normally. + +\var{ExitCode} is always passed to the operating system as the exit-code of +your process. + +\section{Functions and Procedures} +\function{Abs}{(X : Every numerical type)}{Every numerical type} +{\var{Abs} returns the absolute value of a variable. The result of the +function has the same type as its argument, which can be any numerical +type.} +{None.} +{\seef{Round}} + +\input{refex/ex1.tex} + +\function{Addr}{(X : Any type)}{Pointer} +{\var{Addr} returns a pointer to its argument, which can be any type, or a +function or procedure name. The returned pointer isn't typed. +The same result can be obtained by the \var{@} operator, which can return a +typed pointer (\progref). } +{None} +{\seef{SizeOf}} + +\input{refex/ex2.tex} + +\procedure{Append}{(Var F : Text)} +{\var{Append} opens an existing file in append mode. Any data written to +\var{F} will be appended to the file. If the file didn't exist, it will be +created, contrary to the Turbo Pascal implementation of \var{Append}, where +a file needed to exist in order to be opened by +append. + +Only text files can be opened in append mode. +} +{If the file can't be created, a run-time error will be generated.} +{\seep{Rewrite},\seep{Append}, \seep{Reset}} + +\input{refex/ex3.tex} + +\function{Arctan}{(X : Real)}{Real} +{\var{Arctan} returns the Arctangent of \var{X}, which can be any real type. +The resulting angle is in radial units.}{None}{\seef{Sin}, \seef{Cos}} + +\input{refex/ex4.tex} + +\procedure{Assign}{(Var F; Name : String)} +{\var{Assign} assigns a name to \var{F}, which can be any file type. +This call doesn't open the file, it just assigns a name to a file variable, +and marks the file as closed.} +{None.} +{\seep{Reset}, \seep{Rewrite}, \seep{Append}} + +\input{refex/ex5.tex} + +\procedure{Blockread}{(Var F : File; Var Buffer; Var Count : Longint [; var +Result : Longint])} +{\var{Blockread} reads \var{count} or less records from file \var{F}. The +result is placed in \var{Buffer}, which must contain enough room for +\var{Count} records. The function cannot read partial records. + +If \var{Result} is specified, it contains the number of records actually +read. If \var{Result} isn't specified, and less than \var{Count} records were +read, a run-time error is generated. This behavior can be controlled by the +\var{\{\$i\}} switch. } +{If \var{Result} isn't specified, then a run-time error is generated if less +than \var{count} records were read.} +{\seep{Blockwrite},\seep{Reset}, \seep{Assign}} + +\input{refex/ex6.tex} + +\procedure{Blockwrite}{(Var F : File; Var Buffer; Var Count : Longint)} +{\var{Blockread} writes \var{count} records from \var{buffer} to the file + \var{F}. +If the records couldn't be written to disk, a run-time error is generated. +This behavior can be controlled by the \var{\{\$i\}} switch. +} +{A run-time error is generated if, for some reason, the records couldn't be +written to disk.} +{\seep{Blockread},\seep{Reset}, \seep{Assign}} + +For the example, see \seep{Blockread}. + +\procedure{Chdir}{(const S : string)} +{\var{Chdir} changes the working directory of the process to \var{S}.} +{If the directory \var{S} doesn't exist, a run-time error is generated.} +{\seep{Mkdir}, \seep{Rmdir}} + +\input{refex/ex7.tex} + +\function{Chr}{(X : byte)}{Char} +{\var{Chr} returns the character which has ASCII value \var{X}.} +{None.} +{\seef{Ord},\seep{Str}} + +\input{refex/ex8.tex} + +\procedure{Close}{(Var F : Anyfiletype)} +{\var{Close} flushes the buffer of the file \var{F} and closes \var{F}. +After a call to \var{Close}, data can no longer be read from or written to +\var{F}. + +To reopen a file closed with \var{Close}, it isn't necessary to assign the +file again. A call to \seep{Reset} or \seep{Rewrite} is sufficient.} +{None.}{\seep{Assign}, \seep{Reset}, \seep{Rewrite}} + +\input{refex/ex9.tex} + +\function{Concat}{(S1,S2 [,S3, ... ,Sn])}{String} +{\var{Concat} concatenates the strings \var{S1},\var{S2} etc. to one long +string. The resulting string is truncated at a length of 255 bytes. + +The same operation can be performed with the \var{+} operation.} +{None.} +{\seef{Copy}, \seep{Delete}, \seep{Insert}, \seef{Pos}, \seef{Length}} + +\input{refex/ex10.tex} + +\function{Copy}{(Const S : String;Index : Integer;Count : Byte)}{String} +{\var{Copy} returns a string which is a copy if the \var{Count} characters +in \var{S}, starting at position \var{Index}. If \var{Count} is larger than +the length of the string \var{S}, the result is truncated. + +If \var{Index} is larger than the length of the string \var{S}, then an +empty string is returned.} +{None.} +{\seep{Delete}, \seep{Insert}, \seef{Pos}} + +\input{refex/ex11.tex} + +\function{Cos}{(X : real)}{Real} +{\var{Cos} returns the cosine of \var{X}, where X is an angle, in radians.} +{None.} +{\seef{Arctan}, \seef{Sin}} + +\input{refex/ex12.tex} + +\Function{CSeg}{Word} +{\var{CSeg} returns the Code segment register. In \fpk, it returns always a +zero, since \fpk is a 32 bit compiler.} +{None.} +{\seef{DSeg}, \seef{Seg}, \seef{Ofs}, \seef{Ptr}} + +\input{refex/ex13.tex} + +\procedure{Dec}{(Var X : Any ordinal type[; Decrement : Longint])} +{\var{Dec} decreases the value of \var{X} with \var{Decrement}. +If \var{Decrement} isn't specified, then 1 is taken as a default.} +{A range check can occur, or an underflow error, if you try to decrease \var{X} +below its minimum value.} +{\seep{Inc}} + +\input{refex/ex14.tex} + +\procedure{Delete}{(var S : string;Index : Integer;Count : Integer)} +{\var{Delete} removes \var{Count} characters from string \var{S}, starting +at position \var{Index}. All remaining characters are shifted \var{Count} +positions to the left, and the length of the string is adjusted. +} +{None.} +{\seef{Copy},\seef{Pos},\seep{Insert}} + +\input{refex/ex15.tex} + +\procedure{Dispose}{(P : pointer)} +{\var{Dispose} releases the memory allocated with a call to \seep{New}. +The pointer \var{P} must be typed. The released memory is returned to the +heap.} +{An error will occur if the pointer doesn't point to a location in the +heap.} +{\seep{New}, \seep{Getmem}, \seep{Freemem}} + +\input{refex/ex16.tex} + +\Function{DSeg}{Word} +{\var{DSeg} returns the data segment register. In \fpk, it returns always a +zero, since \fpk is a 32 bit compiler.} +{None.} +{\seef{CSeg}, \seef{Seg}, \seef{Ofs}, \seef{Ptr}} + +\input{refex/ex17.tex} + +\function{Eof}{[(F : Any file type)]}{Boolean} +{\var{Eof} returns \var{True} if the file-pointer has reached the end of the +file, or if the file is empty. In all other cases \var{Eof} returns +\var{False}. + +If no file \var{F} is specified, standard input is assumed.} +{None.} +{\seef{Eoln}, \seep{Assign}, \seep{Reset}, \seep{Rewrite}} + +\input{refex/ex18.tex} + +\function{Eoln}{[(F : Text)]}{Boolean} +{\var{Eof} returns \var{True} if the file pointer has reached the end of a +line, which is demarcated by a line-feed character (ASCII value 10), or if +the end of the file is reached. +In all other cases \var{Eof} returns \var{False}. + +If no file \var{F} is specified, standard input is assumed. +It can only be used on files of type \var{Text}.} +{None.} +{\seef{Eof}, \seep{Assign}, \seep{Reset}, \seep{Rewrite}} + +\input{refex/ex19.tex} + +\procedure{Erase}{(Var F : Any file type)} +{\var{Erase} removes an unopened file from disk. The file should be +assigned with \var{Assign}, but not opened with \var{Reset} or \var{Rewrite}} +{A run-time error will be generated if the specified file doesn't exist.} +{\seep{Assign}} + +\input{refex/ex20.tex} + +\procedure{Exit}{([Var X : return type )]} +{\var{Exit} exits the current subroutine, and returns control to the calling +routine. If invoked in the main program routine, exit stops the program. + +The optional argument \var{X} allows to specify a return value, in the case +\var{Exit} is invoked in a function. The function result will then be +equal to \var{X}.} +{None.} +{\seep{Halt}} + +\input{refex/ex21.tex} + +\function{Exp}{(Var X : real)}{Real} +{\var{Exp} returns the exponent of \var{X}, i.e. the number \var{e} to the +power \var{X}.} +{None.}{\seef{Ln}} + +\input{refex/ex22.tex} + +\function{Filepos}{(Var F : Any file type)}{Longint} +{\var{Filepos} returns the current record position of the file-pointer in file +\var{F}. It cannot be invoked with a file of type \var{Text}.} +{None.} +{\seef{Filesize}} + +\input{refex/ex23.tex} + +\function{Filesize}{(Var F : Any file type)}{Longint} +{\var{Filepos} returns the total number of records in file \var{F}. +It cannot be invoked with a file of type \var{Text}. (under \linux, this +also means that it cannot be invoked on pipes.) + +If \var{F} is empty, 0 is returned. +} +{None.} +{\seef{Filepos}} + +\input{refex/ex24.tex} + +\procedure{Fillchar}{(Var X;Count : Longint;Value : char or byte);} +{\var{Fillchar} fills the memory starting at \var{X} with \var{Count} bytes +or characters with value equal to \var{Value}. +} +{No checking on the size of \var{X} is done.} +{\seep{Fillword}, \seep{Move}} + +\input{refex/ex25.tex} + +\procedure{Fillword}{(Var X;Count : Longint;Value : Word);} +{\var{Fillword} fills the memory starting at \var{X} with \var{Count} words +with value equal to \var{Value}. +} +{No checking on the size of \var{X} is done.} +{\seep{Fillword}, \seep{Move}} + +\input{refex/ex76.tex} + +\procedure{Flush}{(Var F : Text)} +{\var{Flush} empties the internal buffer of file \var{F} and writes the +contents to disk. The file is \textit{not} closed as a result of this call.} +{If the disk is full, a run-time error will be generated.} +{\seep{Close}} + +\input{refex/ex26.tex} + +\function{Frac}{(X : real)}{Real} +{\var{Frac} returns the non-integer part of \var{X}.} +{None.} +{\seef{Round}, \seef{Int}} + +\input{refex/ex27.tex} + +\procedure{Freemem}{(Var P : pointer; Count : longint)} +{\var{Freemem} releases the memory occupied by the pointer \var{P}, of size +\var{Count}, and returns it to the heap. \var{P} should point to the memory +allocated to a dynamical variable.} +{An error will occur when \var{P} doesn't point to the heap.} +{\seep{Getmem}, \seep{New}, \seep{Dispose}} + +\input{refex/ex28.tex} + +\procedure{Getdir}{(drivenr : byte;var dir : string)} +{\var{Getdir} returns in \var{dir} the current directory on the drive +\var{drivenr}, where {drivenr} is 1 for the first floppy drive, 3 for the +first hard disk etc. A value of 0 returns the directory on the current disk. + +On \linux, \var{drivenr} is ignored, as there is only one directory tree.} +{An error is returned under \dos, if the drive requested isn't ready.} +{\seep{Chdir}} + +\input{refex/ex29.tex} + +\procedure{Getmem}{(var p : pointer;size : longint)} +{\var{Getmem} reserves \var{Size} bytes memory on the heap, and returns a +pointer to this memory in \var{p}. If no more memory is available, nil is +returned.} +{None.} +{\seep{Freemem}, \seep{Dispose}, \seep{New}} + +For an example, see \seep{Freemem}. + +\procedure{Halt}{[(Errnum : byte]} +{\var{Halt} stops program execution and returns control to the calling +program. The optional argument \var{Errnum} specifies an exit value. If +omitted, zero is returned.} +{None.} +{\seep{Exit}} + +\input{refex/ex30.tex} + +\function{Hi}{(X : Ordinal type)}{Word or byte} +{\var{Hi} returns the high byte or word from \var{X}, depending on the size +of X. If the size of X is 4, then the high word is returned. If the size is +2 then the high byte is retuned. +\var{hi} cannot be invoked on types of size 1, such as byte or char.} +{None} +{\seef{Lo}} + +\input{refex/ex31.tex} + +\procedure{Inc}{(Var X : Any ordinal type[; Increment : Longint])} +{\var{Inc} increases the value of \var{X} with \var{Increment}. +If \var{Increment} isn't specified, then 1 is taken as a default.} +{A range check can occur, or an overflow error, if you try to increase \var{X} +over its maximum value.} +{\seep{Dec}} + +\input{refex/ex32.tex} + +\procedure{Insert}{(Var Source : String;var S : String;Index : integer)} +{\var{Insert} inserts string \var{S} in string \var{Source}, at position +\var{Index}, shifting all characters after \var{Index} to the right. The +resulting string is truncated at 255 characters, if needed.} +{None.} +{\seep{Delete}, \seef{Copy}, \seef{Pos}} + +\input{refex/ex33.tex} + +\function{Int}{(X : real)}{Real} +{\var{Int} returns the integer part of any real \var{X}, as a real.} +{None.} +{\seef{Frac}, \seef{Round}} + +\input{refex/ex34.tex} + +\Function{IOresult}{Word} +{IOresult contains the result of any input/output call, when the +\var{\{\$i-\}} compiler directive is active, and IO checking is disabled. When the +flag is read, it is reset to zero. + +If \var{IOresult} is zero, the operation completed successfully. If +non-zero, an error occurred. The following errors can occur: + +\dos errors : + +\begin{description} +\item [2\ ] File not found. +\item [3\ ] Path not found. +\item [4\ ] Too many open files. +\item [5\ ] Access denied. +\item [6\ ] Invalid file handle. +\item [12\ ] Invalid file-access mode. +\item [15\ ] Invalid disk number. +\item [16\ ] Cannot remove current directory. +\item [17\ ] Cannot rename across volumes. +\end{description} + +I/O errors : + +\begin{description} +\item [100\ ] Error when reading from disk. +\item [101\ ] Error when writing to disk. +\item [102\ ] File not assigned. +\item [103\ ] File not open. +\item [104\ ] File not opened for input. +\item [105\ ] File not opened for output. +\item [106\ ] Invalid number. +\end{description} + +Fatal errors : + +\begin{description} +\item [150\ ] Disk is write protected. +\item [151\ ] Unknown device. +\item [152\ ] Drive not ready. +\item [153\ ] Unknown command. +\item [154\ ] CRC check failed. +\item [155\ ] Invalid drive specified.. +\item [156\ ] Seek error on disk. +\item [157\ ] Invalid media type. +\item [158\ ] Sector not found. +\item [159\ ] Printer out of paper. +\item [160\ ] Error when writing to device. +\item [161\ ] Error when reading from device. +\item [162\ ] Hardware failure. +\end{description} +} +{None.} +{All I/O functions.} + +\input{refex/ex35.tex} + +\function{Length}{(S : String)}{Byte} +{\var{Length} returns the length of the string \var{S}, +which is limited to 255. If the strings \var{S} is empty, 0 is returned. + +{\em Note:} The length of the string \var{S} is stored in \var{S[0]}. +} +{None.} +{\seef{Pos}} + +\input{refex/ex36.tex} + +\function{Ln}{(X : real)}{Real} +{ +\var{Ln} returns the natural logarithm of the real parameter \var{X}. +\var{X} must be positive. +} +{An run-time error will occur when \var{X} is negative.} +{\seef{Exp}} + +\input{refex/ex37.tex} + +\function{Lo}{(O : Word or Longint)}{Byte or Word} +{\var{Lo} returns the low byte of its argument if this is of type +\var{Integer} or +\var{Word}. It returns the low word of its argument if this is of type +\var{Longint} or \var{Cardinal}.} +{None.} +{\seef{Ord}, \seef{Chr}} + +\input{refex/ex38.tex} + +\function{Lowercase}{(C : Char or String)}{Char or String} +{\var{Lowercase} returns the lowercase version of its argument \var{C}. +If its argument is a string, then the complete string is converted to +lowercase. The type of the returned value is the same as the type of the +argument.} +{None.} +{\seef{Upcase}} + +\input{refex/ex73.tex} + +\procedure{Mark}{(Var P : Pointer)} +{\var{Mark} copies the current heap-pointer to \var{P}.} +{None.} +{\seep{Getmem}, \seep{Freemem}, \seep{New}, \seep{Dispose}, \seef{Maxavail}} + +\input{refex/ex39.tex} + +\Function{Maxavail}{Longint} +{\var{Maxavail} returns the size, in bytes, of the biggest free memory block in +the heap. + +{\em Remark:} The heap grows dynamically if more memory is needed than is +available.} +{None.} +{\seep{Release}, \seef{Memavail},\seep{Freemem}, \seep{Getmem}} + +\input{refex/ex40.tex} + +\Function{Memavail}{Longint} +{\var{Memavail} returns the size, in bytes, of the free heap memory. + +{\em Remark:} The heap grows dynamically if more memory is needed than is +available.} +{None.} +{\seef{Maxavail},\seep{Freemem}, \seep{Getmem}} + +\input{refex/ex41.tex} + +\procedure{Mkdir}{(const S : string)} +{\var{Chdir} creates a new directory \var{S}.} +{If a parent-directory of directory \var{S} doesn't exist, a run-time error is generated.} +{\seep{Chdir}, \seep{Rmdir}} + +For an example, see \seep{Rmdir}. + +\procedure{Move}{(var Source,Dest;Count : longint)} +{\var{Move} moves \var{Count} bytes from \var{Source} to \var{Dest}.} +{If either \var{Dest} or \var{Source} is outside the accessible memory for +the process, then a run-time error will be generated. With older versions of +the compiler, a segmentation-fault will occur. } +{\seep{Fillword}, \seep{Fillchar}} + +\input{refex/ex42.tex} + + +\procedure{New}{(Var P : Pointer[, Constructor])} +{\var{New} allocates a new instance of the type pointed to by \var{P}, and +puts the address in \var{P}. + +If P is an object, then it is possible to +specify the name of the constructor with which the instance will be created.} +{If not enough memory is available, \var{Nil} will be returned.} +{\seep{Dispose}, \seep{Freemem}, \seep{Getmem}, \seef{Memavail}, +\seef{Maxavail}} + +For an example, see \seep{Dispose}. + +\function{Odd}{(X : longint)}{Boolean} +{\var{Odd} returns \var{True} if \var{X} is odd, or \var{False} otherwise.} +{None.} +{\seef{Abs}, \seef{Ord}} + + +\input{refex/ex43.tex} + +\function{Ofs}{Var X}{Longint} +{\var{Ofs} returns the offset of the address of a variable. + +This function is only supported for compatibility. In \fpk, it +returns always the complete address of the variable, since \fpk is a 32 bit +compiler. +} +{None.} +{\seef{DSeg}, \seef{CSeg}, \seef{Seg}, \seef{Ptr}} + + +\input{refex/ex44.tex} + + +\function{Ord}{(X : Ordinal type)}{Byte} +{\var{Ord} returns the Ordinal value of a ordinal-type variable \var{X}.} +{None.} +{\seef{Chr}} + + +\input{refex/ex45.tex} + +\Function{Paramcount}{Longint} +{\var{Paramcount} returns the number of command-line arguments. If no +arguments were given to the running program, \var{0} is returned. +} +{None.} +{\seef{Paramstr}} + + +\input{refex/ex46.tex} + +\function{Paramstr}{(L : Longint)}{String} +{\var{Paramstr} returns the \var{L}-th command-line argument. \var{L} must +be between \var{0} and \var{Paramcount}, these values included. +The zeroth argument is the name with which the program was started. +} +{Under Linux, command-line arguments may be longer than 255 characters. In +that case, the string is truncated. If you want to access the complete +string, you must use the \var{argv} pointer to access the real values of the +command-line parameters.} +{\seef{Paramcount}} + +For an example, see \seef{Paramcount}. + +\Function{Pi}{Real} +{\var{Pi} returns the value of Pi (3.1415926535897932385).} +{None.} +{\seef{Cos}, \seef{Sin}} + + +\input{refex/ex47.tex} + +\function{Pos}{(Const Substr : String;Const S : String)}{Byte} +{\var{Pos} returns the index of \var{Substr} in \var{S}, if \var{S} contains +\var{Substr}. In case \var{Substr} isn't found, \var{0} is returned. + +The search is case-sensitive. +} +{None} +{\seef{Length}, \seef{Copy}, \seep{Delete}, \seep{Insert}} + + +\input{refex/ex48.tex} + +\function{Ptr}{(Sel,Off : Longint)}{Pointer} +{\var{Ptr} returns a pointer, pointing to the address specified by +segment{Sel} and offset \var{Off}. + +{\em Remark 1:} In the 32-bit flat-memory model supported by \fpk, this +function is obsolete.} + +{\em Remark 2:} The returned address is simply the offset. If you recompile +the RTL with \var{-dDoMapping} defined, then the compiler returns the +following : \verb|ptr:=pointer($e0000000+sel shl 4+off)| under \dos, or +\verb|ptr:=pointer(sel shl 4+off)| on other OSes. +{None.} +{\seef{Addr}} +\input{refex/ex59.tex} + +\function{Random}{[(L : longint)]}{Longint or Real} +{\var{Random} returns a random number larger or equal to \var{0} and +strictly less than \var{L}. + +If the argument \var{L} is omitted, a real number between 0 and 1 is returned. +(0 included, 1 excluded)} +{None.} +{\seep{Randomize}} + + +\input{refex/ex49.tex} + +\Procedure{Randomize} +{\var{Randomize} initializes the random number generator of \fpk, by giving +a value to \var{Randseed}, calculated with the system clock. +} +{None.} +{\seef{Random}} + +For an example, see \seef{Random}. + +\procedure{Read}{([Var F : Any file type], V1 [, V2, ... , Vn])} +{\var{Read} reads one or more values from a file \var{F}, and stores the +result in \var{V1}, \var{V2}, etc.; If no file \var{F} is specified, then +standard input is read. + +If \var{F} is of type \var{Text}, then the variables \var{V1, V2} etc. must be +of type \var{Char}, \var{Integer}, \var{Real} or \var{String}. + +If \var{F} is a typed file, then each of the variables must be of the type +specified in the declaration of \var{F}. Untyped files are not allowed as an +argument.} +{If no data is available, a run-time error is generated. This behavior can + +be controlled with the \var{\{\$i\}} compiler switch.} +{\seep{Readln}, \seep{Blockread}, \seep{Write}, \seep{Blockwrite}} + + +\input{refex/ex50.tex} + +\procedure{Readln}{[Var F : Text], V1 [, V2, ... , Vn])} +{\var{Read} reads one or more values from a file \var{F}, and stores the +result in \var{V1}, \var{V2}, etc. After that it goes to the next line in +the file (defined by the \var{LineFeed (\#10)} character). +If no file \var{F} is specified, then standard input is read. + +The variables \var{V1, V2} etc. must be of type \var{Char}, \var{Integer}, +\var{Real}, \var{String} or \var{PChar}. +} +{If no data is available, a run-time error is generated. This behavior can +be controlled with the \var{\{\$i\}} compiler switch.} +{\seep{Read}, \seep{Blockread}, \seep{Write}, \seep{Blockwrite}} + +For an example, see \seep{Read}. + +\procedure{Release}{(Var P : pointer)} +{\var{Release} sets the top of the Heap to the location pointed to by +\var{P}. All memory at a location higher than \var{P} is marked empty.} +{A run-time error will be generated if \var{P} points to memory outside the +heap.} +{\seep{Mark}, \seef{Memavail}, \seef{Maxavail}, \seep{Getmem}, \seep{Freemem} +\seep{New}, \seep{Dispose}} + +For an example, see \seep{Mark}. + +\procedure{Rename}{(Var F : Any Filetype; Const S : String)} +{\var{Rename} changes the name of the assigned file \var{F} to \var{S}. +\var{F} +must be assigned, but not opened.} +{A run-time error will be generated if \var{F} isn't assigned, +or doesn't exist.} +{\seep{Erase}} + +\input{refex/ex77.tex} + +\procedure{Reset}{(Var F : Any File Type[; L : longint])} +{\var{Reset} opens a file \var{F} for reading. \var{F} can be any file type. +If \var{F} is an untyped or typed file, then it is opened for reading and +writing. If \var{F} is an untyped file, the record size can be specified in +the optional parameter \var{L}. Default a value of 128 is used.} +{If the file cannot be opened for reading, then a run-time error is +generated. This behavior can be changed by the \var{\{\$i\} } compiler switch.} +{\seep{Rewrite}, \seep{Assign}, \seep{Close}} + + +\input{refex/ex51.tex} + +\procedure{Rewrite}{(Var F : Any File Type[; L : longint])} +{\var{Rewrite} opens a file \var{F} for writing. \var{F} can be any file type. +If \var{F} is an untyped or typed file, then it is opened for reading and +writing. If \var{F} is an untyped file, the record size can be specified in +the optional parameter \var{L}. Default a value of 128 is used. + +if \var{Rewrite} finds a file with the same name as \var{F}, this file is +truncated to length \var{0}. If it doesn't find such a file, a new file is +created. +} +{If the file cannot be opened for writing, then a run-time error is +generated. This behavior can be changed by the \var{\{\$i\} } compiler switch.} +{\seep{Reset}, \seep{Assign}, \seep{Close}} + + +\input{refex/ex52.tex} + +\procedure{Rmdir}{(const S : string)} +{\var{Rmdir} removes the directory \var{S}.} +{If \var{S} doesn't exist, or isn't empty, a run-time error is generated. +} +{\seep{Chdir}, \seep{Rmdir}} + +\input{refex/ex53.tex} + +\function{Round}{(X : real)}{Longint} +{\var{Round} rounds \var{X} to the closest integer, which may be bigger or +smaller than \var{X}.} +{None.} +{\seef{Frac}, \seef{Int}, \seef{Trunc}} + +\input{refex/ex54.tex} + +\procedure{Runerror}{(ErrorCode : Word)} +{\var{Runerror} stops the execution of the program, and generates a +run-time error \var{ErrorCode}.} +{None.} +{\seep{Exit}, \seep{Halt}} + +\input{refex/ex55.tex} + +\procedure{Seek}{(Var F; Count : Longint)} +{\var{Seek} sets the file-pointer for file \var{F} to record Nr. \var{Count}. +The first record in a file has \var{Count=0}. F can be any file type, except +\var{Text}. If \var{F} is an untyped file, with no specified record size, 128 +is assumed.} +{A run-time error is generated if \var{Count} points to a position outside +the file, or the file isn't opened.} +{\seef{Eof}, \seef{SeekEof}, \seef{SeekEoln}} + +\input{refex/ex56.tex} + +\function{SeekEof}{[(Var F : text)]}{Boolean} +{\var{SeekEof} returns \var{True} is the file-pointer is at the end of the +file. It ignores all whitespace. + +Calling this function has the effect that the file-position is advanced +until the first non-whitespace character or the end-of-file marker is +reached. +If the end-of-file marker is reached, \var{True} is returned. Otherwise, +False is returned. + +If the parameter \var{F} is omitted, standard \var{Input} is assumed. +} +{A run-time error is generated if the file \var{F} isn't opened.} +{\seef{Eof}, \seef{SeekEoln}, \seep{Seek}} + +\input{refex/ex57.tex} + +\function{SeekEoln}{[(Var F : text)]}{Boolean} +{\var{SeekEoln} returns \var{True} is the file-pointer is at the end of the +current line. It ignores all whitespace. + +Calling this function has the effect that the file-position is advanced +until the first non-whitespace character or the end-of-line marker is +reached. +If the end-of-line marker is reached, \var{True} is returned. Otherwise, +False is returned. + +The end-of-line marker is defined as \var{\#10}, the LineFeed character. + +If the parameter \var{F} is omitted, standard \var{Input} is assumed.} +{A run-time error is generated if the file \var{F} isn't opened.} +{\seef{Eof}, \seef{SeekEof}, \seep{Seek}} + +\input{refex/ex58.tex} + +\function{Seg}{Var X}{Longint} +{\var{Seg} returns the segment of the address of a variable. + +This function is only supported for compatibility. In \fpk, it +returns always 0, since \fpk is a 32 bit compiler, segments have no meaning. +} +{None.} +{\seef{DSeg}, \seef{CSeg}, \seef{Ofs}, \seef{Ptr}} + +\input{refex/ex60.tex} + + +\procedure{SetTextBuf}{(Var f : Text; Var Buf[; Size : Word])} +{\var{SetTextBuf} assigns an I/O buffer to a text file. The new buffer is +located at \var{Buf} and is \var{Size} bytes long. If \var{Size} is omitted, +then \var{SizeOf(Buf)} is assumed. + +The standard buffer of any text file is 128 bytes long. For heavy I/0 +operations this may prove too slow. The \var{SetTextBuf} procedure allows +you to set a bigger buffer for your application, thus reducing the number of +system calls, and thus reducing the load on the system resources. + +The maximum size of the newly assigned buffer is 65355 bytes. + +{\em Remark 1:} Never assign a new buffer to an opened file. You can assign a +new buffer immediately after a call to \seep{Rewrite}, \seep{Reset} or +\var{Append}, but not after you read from/wrote to the file. This may cause +loss of data. If you still want to assign a new buffer after read/write +operations have been performed, flush the file first. This will ensure that +the current buffer is emptied. + +{\em Remark 2:} Take care that the buffer you assign is always valid. If you +assign a local variable as a buffer, then after your program exits the local +program block, the buffer will no longer be valid, and stack problems may +occur. +} +{No checking on \var{Size} is done.} +{\seep{Assign}, \seep{Reset}, \seep{Rewrite}, \seep{Append}} + +\input{refex/ex61.tex} + +\function{Sin}{(X : real)}{Real} +{\var{Sin} returns the sine of its argument \var{X}, where \var{X} is an +angle in radians.} +{None.} +{\seef{Cos}, \seef{Pi}, \seef{Exp}} + +\input{refex/ex62.tex} + +\function{SizeOf}{(X : Any Type)}{Longint} +{\var{SizeOf} Returns the size, in bytes, of any variable or type-identifier. + + {\em Remark:} this isn't really a RTL function. Its result is calculated at +compile-time, and hard-coded in your executable.} +{None.} +{\seef{Addr}} + +\input{refex/ex63.tex} + +\Function{Sptr}{Pointer} +{\var{Sptr} returns the current stack pointer. +}{None.}{} + +\input{refex/ex64.tex} + +\function{Sqr}{(X : Real)}{Real} +{\var{Sqr} returns the square of its argument \var{X}.} +{None.} +{\seef{Sqrt}, \seef{Ln}, \seef{Exp}} + +\input{refex/ex65.tex} + +\function{Sqrt}{(X : Real)}{Real} +{\var{Sqrt} returns the square root of its argument \var{X}, which must be +positive.} +{If \var{X} is negative, then a run-time error is generated.} +{\seef{Sqr}, \seef{Ln}, \seef{Exp}} + +\input{refex/ex66.tex} + +\Function{SSeg}{Longint} +{ \var{SSeg} returns the Stack Segment. This function is only + supported for compatibolity reasons, as \var{Sptr} returns the +correct contents of the stackpointer.} +{None.}{\seef{Sptr}} + +\input{refex/ex67.tex} + + +\procedure{Str}{(Var X[:NumPlaces[:Decimals]]; Var S : String)} +{\var{Str} returns a string which represents the value of X. X can be any +numerical type. + +The optional \var{NumPLaces} and \var{Decimals} specifiers control the +formatting of the string.} +{None.} +{\seep{Val}} + +\input{refex/ex68.tex} + +\function{Swap}{(X)}{Type of X} +{\var{Swap} swaps the high and low order bytes of \var{X} if \var{X} is of +type \var{Word} or \var{Integer}, or swaps the high and low order words of +\var{X} if \var{X} is of type \var{Longint} or \var{Cardinal}. + +The return type is the type of \var{X}} +{None.}{\seef{Lo}, \seef{Hi}} + +\input{refex/ex69.tex} + +\function{Trunc}{(X : real)}{Longint} +{\var{Trunc} returns the integer part of \var{X}, +which is always smaller than (or equal to) \var{X}.} +{None.} +{\seef{Frac}, \seef{Int}, \seef{Trunc}} + +\input{refex/ex70.tex} + +\procedure{Truncate}{(Var F : file)} +{\var{Truncate} truncates the (opened) file \var{F} at the current file +position. +}{Errors are reported by IOresult.}{\seep{Append}, \seef{Filepos}, +\seep{Seek}} + +\input{refex/ex71.tex} + +\function{Upcase}{(C : Char or string)}{Char or String} +{\var{Upcase} returns the uppercase version of its argument \var{C}. +If its argument is a string, then the complete string is converted to +uppercase. The type of the returned value is the same as the type of the +argument.} +{None.} +{\seef{Lowercase}} + +\input{refex/ex72.tex} + +\procedure{Val}{(const S : string;var V;var Code : word)} +{\var{Val} converts the value represented in the string \var{S} to a numerical +value, and stores this value in the variable \var{V}, which +can be of type \var{Longint}, \var{real} and \var{Byte}. + +If the conversion isn't succesfull, then the parameter \var{Code} contains +the index of the character in \var{S} which prevented the conversion. + +The string \var{S} isn't allow to contain spaces.} +{If the conversion doesn't succeed, the value of \var{Code} indicates the +position where the conversion went wrong.} +{\seep{Str}} + +\input{refex/ex74.tex} + +\procedure{Write}{([Var F : Any filetype;] V1 [; V2; ... , Vn)]} +{\var{Write} writes the contents of the variables \var{V1}, \var{V2} etc. to +the file \var{F}. \var{F} can be a typed file, or a \var{Text} file. + +If \var{F} is a typed file, then the variables \var{V1}, \var{V2} etc. must +be of the same type as the type in the declaration of \var{F}. Untyped files +are not allowed. + +If the parameter \var{F} is omitted, standard output is assumed. + +If \var{F} is of type \var{Text}, then the necessary conversions are done +such that the output of the variables is in human-readable format. +This conversion is done for all numerical types. Strings are printed exactly +as they are in memory, as well as \var{PChar} types. +The format of the numerical conversions can be influenced through +the following modifiers: + +\var{ OutputVariable : NumChars [: Decimals ] } + +This will print the value of \var{OutputVariable} with a minimum of +\var{NumChars} characters, from which \var{Decimals} are reserved for the +decimals. If the number cannot be represented with \var{NumChars} characters, +\var{NumChars} will be increased, until the representation fits. If the +representation requires less than \var{NumChars} characters then the output +is filled up with spaces, to the left of the generated string, thus +resulting in a right-aligned representation. + +If no formatting is specified, then the number is written using its natural +length, with a space in front of it if it's positive, and a minus sign if +it's negative. + +Real numbers are, by default, written in scientific notation. +} +{If an error occurs, a run-time error is generated. This behavior can be +controlled with the \var{\{\$i\}} switch. } +{\seep{Writeln}, \seep{Read}, \seep{Readln}, \seep{Blockwrite} } + +\procedure{Writeln}{[([Var F : Text;] [V1 [; V2; ... , Vn)]]} +{\var{Writeln} does the same as \seep{Write} for text files, and emits a +Carriage Return - LineFeed character pair after that. + +If the parameter \var{F} is omitted, standard output is assumed. + +If no variables are specified, a Carriage Return - LineFeed character pair +is emitted, resulting in a new line in the file \var{F}. + +{\em Remark:} Under \linux, the Carriage Return character is omitted, as +customary in Unix environments. +} +{If an error occurs, a run-time error is generated. This behavior can be +controlled with the \var{\{\$i\}} switch. } +{\seep{Write}, \seep{Read}, \seep{Readln}, \seep{Blockwrite}} + +\input{refex/ex75.tex} + +% +% The index. +% +\printindex +\end{document} diff --git a/docs/refex/Makefile b/docs/refex/Makefile new file mode 100644 index 0000000000..b82e072f54 --- /dev/null +++ b/docs/refex/Makefile @@ -0,0 +1,58 @@ +####################################################################### +# +# Makefile to compile all examples and convert them to LaTeX +# +####################################################################### + +# Compiler +PP=ppc386 + +# Unit directory +# UNITDIR=/usr/lib/ppc/0.99.0/linuxunits + + +# Any options you wish to pass. +PPOPTS= + +# Script to convert the programs to LaTeX examples which can be included. +PP2TEX=pp2tex + +# Script to collect all examples in 1 file. +MAKETEX=make1tex + +####################################################################### +# No need to edit after this line. +####################################################################### + +ifdef UNITDIR +PPOPTS:=$(PPOPTS) -Up$(UNITDIR); +endif + +.SUFFIXES: .pp .tex + +.PHONY: all tex clean + +OBJECTS=ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex11 ex12 ex13 ex14 \ + ex15 ex16 ex17 ex18 ex19 ex20 ex21 ex22 ex23 ex24 ex25 ex26 ex27 \ + ex28 ex29 ex30 ex31 ex32 ex33 ex34 ex35 ex36 ex37 ex38 ex39 ex40 \ + ex41 ex42 ex43 ex44 ex45 ex46 ex47 ex48 ex49 ex50 ex51 ex52 ex53 \ + ex54 ex55 ex56 ex57 ex58 ex59 ex60 ex61 ex62 ex63 ex64 ex65 ex66 \ + ex67 ex68 ex69 ex70 ex71 ex72 ex73 ex74 ex75 ex76 ex77 + +TEXOBJECTS=$(addsuffix .tex, $(OBJECTS)) + +all : $(OBJECTS) + +tex : $(TEXOBJECTS) + +onetex : tex + $(MAKETEX) $(TEXOBJECTS) + +clean : + rm -f *.o *.s $(OBJECTS) $(TEXOBJECTS) + +$(OBJECTS): %: %.pp + $(PP) $(PPOPTS) $* + +$(TEXOBJECTS): %.tex: %.pp head.tex foot.tex + $(PP2TEX) $* diff --git a/docs/refex/README b/docs/refex/README new file mode 100644 index 0000000000..41b2981a78 --- /dev/null +++ b/docs/refex/README @@ -0,0 +1,83 @@ +These are the example programs that appear in the FPC documentation. + +Reference guide : + +ex1.pp contains an example of the Abs function. +ex2.pp contains an example of the Addr function. +ex3.pp contains an example of the Append function. +ex4.pp contains an example of the ArcTan function. +ex5.pp contains an example of the Assign function. +ex6.pp contains an example of the BlockRead and BlockWrite functions. +ex7.pp contains an example of the ChDir function. +ex8.pp contains an example of the Chr function. +ex9.pp contains an example of the Close function. +ex10.pp contains an example of the Concat function. +ex11.pp contains an example of the Copy function. +ex12.pp contains an example of the Cos function. +ex13.pp contains an example of the CSeg function. +ex14.pp contains an example of the Dec function. +ex15.pp contains an example of the Delete function. +ex16.pp contains an example of the Dispose and New functions. +ex17.pp contains an example of the DSeg function. +ex18.pp contains an example of the Eof function. +ex19.pp contains an example of the Eoln function. +ex20.pp contains an example of the Erase function. +ex21.pp contains an example of the Exit function. +ex22.pp contains an example of the Exp function. +ex23.pp contains an example of the FilePos function. +ex24.pp contains an example of the FileSize function. +ex25.pp contains an example of the FillChar function. +ex26.pp contains an example of the Flush function. +ex27.pp contains an example of the Frac function. +ex28.pp contains an example of the FreeMem and GetMem functions. +ex29.pp contains an example of the GetDir function. +ex30.pp contains an example of the Halt function. +ex31.pp contains an example of the Hi function. +ex32.pp contains an example of the Inc function. +ex33.pp contains an example of the Insert function. +ex34.pp contains an example of the Int function. +ex35.pp contains an example of the IOResult function. +ex36.pp contains an example of the Length function. +ex37.pp contains an example of the Ln function. +ex38.pp contains an example of the Lo function. +ex39.pp contains an example of the Mark and Release functions. +ex40.pp contains an example of the MaxAvail function. +ex41.pp contains an example of the MemAvail function. +ex41.pp contains an example of the MemAvail function. +ex42.pp contains an example of the Move function. +ex43.pp contains an example of the Odd function. +ex44.pp contains an example of the Ofs function. +ex45.pp contains an example of the Ord function. +ex46.pp contains an example of the ParamCount and ParamStr functions. +ex47.pp contains an example of the Pi function. +ex48.pp contains an example of the Pos function. +ex49.pp contains an example of the Random function. +ex50.pp contains an example of the Read(Ln) functions. +ex51.pp contains an example of the Reset function. +ex52.pp contains an example of the Rewrite function. +ex53.pp contains an example of the MkDir and RmDir functions. +ex54.pp contains an example of the Round function. +ex55.pp contains an example of the RunError function. +ex56.pp contains an example of the Seek function. +ex57.pp contains an example of the SeekEof function. +ex58.pp contains an example of the SeekEoln function. +ex59.pp contains an example of the Ptr function. +ex60.pp contains an example of the Seg function. +ex61.pp contains an example of the SetTextBuf function. +ex62.pp contains an example of the Sin function. +ex63.pp contains an example of the SizeOf function. +ex64.pp contains an example of the SPtr function. +ex65.pp contains an example of the Sqr function. +ex66.pp contains an example of the Sqrt function. +ex67.pp contains an example of the SSeg function. +ex68.pp contains an example of the Str function. +ex69.pp contains an example of the Swap function. +ex70.pp contains an example of the Trunc function. +ex71.pp contains an example of the Truncate function. +ex72.pp contains an example of the Upcase function. +ex73.pp contains an example of the Lowercase function. +ex74.pp contains an example of the Val function. +ex75.pp contains an example of the Write(ln) function. +ex76.pp contains an example of the FillWord function. +ex77.pp contains an example of the Rename function. +ex59.pp contains an example of the Ptr function. diff --git a/docs/refex/bug1.pp b/docs/refex/bug1.pp new file mode 100644 index 0000000000..0e323ba86b --- /dev/null +++ b/docs/refex/bug1.pp @@ -0,0 +1,11 @@ +Program Example2; + +{ Program to demonstrate the Addr function. } + +Const Zero = 0; + +Var p : pointer; + +begin + p:=Addr(Zero); { P points to 'Zero' ??? } +end. diff --git a/docs/refex/ex1.pp b/docs/refex/ex1.pp new file mode 100644 index 0000000000..784f2c7d47 --- /dev/null +++ b/docs/refex/ex1.pp @@ -0,0 +1,12 @@ +Program Example1; + +{ Program to demonstrate the Abs function. } + +Var + r : real; + i : integer; + +begin + r:=abs(-1.0); { r:=1.0 } + i:=abs(-21); { i:=21 } +end. diff --git a/docs/refex/ex10.pp b/docs/refex/ex10.pp new file mode 100644 index 0000000000..bf52fdf27d --- /dev/null +++ b/docs/refex/ex10.pp @@ -0,0 +1,9 @@ +Program Example10; + +{ Program to demonstrate the Concat function. } +Var + S : String; + +begin + S:=Concat('This can be done',' Easier ','with the + operator !'); +end. diff --git a/docs/refex/ex11.pp b/docs/refex/ex11.pp new file mode 100644 index 0000000000..158b74001d --- /dev/null +++ b/docs/refex/ex11.pp @@ -0,0 +1,12 @@ +Program Example11; + +{ Program to demonstrate the Copy function. } + +Var S,T : String; + +begin + T:='1234567'; + S:=Copy (T,1,2); { S:='12' } + S:=Copy (T,4,2); { S:='45' } + S:=Copy (T,4,8); { S:='4567' } +end. diff --git a/docs/refex/ex12.pp b/docs/refex/ex12.pp new file mode 100644 index 0000000000..ce9f2da977 --- /dev/null +++ b/docs/refex/ex12.pp @@ -0,0 +1,12 @@ +Program Example12; + +{ Program to demonstrate the Cos function. } + +Var R : Real; + +begin + R:=Cos(Pi); { R:=-1 } + R:=Cos(Pi/2); { R:=0 } + R:=Cos(0); { R:=1 } +end. + diff --git a/docs/refex/ex13.pp b/docs/refex/ex13.pp new file mode 100644 index 0000000000..e55ae8df68 --- /dev/null +++ b/docs/refex/ex13.pp @@ -0,0 +1,10 @@ +Program Example13; + +{ Program to demonstrate the CSeg function. } + +var W : word; + +begin + W:=CSeg; {W:=0, provided for comppatibility, + FPC is 32 bit.} +end. diff --git a/docs/refex/ex14.pp b/docs/refex/ex14.pp new file mode 100644 index 0000000000..8898b7de62 --- /dev/null +++ b/docs/refex/ex14.pp @@ -0,0 +1,23 @@ +Program Example14; + +{ Program to demonstrate the Dec function. } + +Var + I : Integer; + L : Longint; + W : Word; + B : Byte; + Si : ShortInt; + +begin + I:=1; + L:=2; + W:=3; + B:=4; + Si:=5; + Dec (i); { i:=0 } + Dec (L,2); { L:=0 } + Dec (W,2); { W:=1 } + Dec (B,-2); { B:=6 } + Dec (Si,0); { Si:=5 } +end. diff --git a/docs/refex/ex15.pp b/docs/refex/ex15.pp new file mode 100644 index 0000000000..80feb8bfc8 --- /dev/null +++ b/docs/refex/ex15.pp @@ -0,0 +1,11 @@ +Program Example15; + +{ Program to demonstrate the Delete function. } + +Var + S : String; + +begin + S:='This is not easy !'; + Delete (S,9,4); { S:='This is easy !' } +end. diff --git a/docs/refex/ex16.pp b/docs/refex/ex16.pp new file mode 100644 index 0000000000..d9c1dee49b --- /dev/null +++ b/docs/refex/ex16.pp @@ -0,0 +1,37 @@ +Program Example16; + +{ Program to demonstrate the Dispose and New functions. } + +Type SS = String[20]; + + AnObj = Object + I : integer; + Constructor Init; + Destructor Done; + end; + +Var + P : ^SS; + T : ^AnObj; + +Constructor Anobj.Init; + +begin + Writeln ('Initializing an instance of AnObj !'); +end; + +Destructor AnObj.Done; + +begin + Writeln ('Destroying an instance of AnObj !'); +end; + +begin + New (P); + P^:='Hello, World !'; + Dispose (P); + { P is undefined from here on !} + New(T,Init); + T^.i:=0; + Dispose (T,Done); +end. diff --git a/docs/refex/ex17.pp b/docs/refex/ex17.pp new file mode 100644 index 0000000000..6cc7bec61d --- /dev/null +++ b/docs/refex/ex17.pp @@ -0,0 +1,11 @@ +Program Example17; + +{ Program to demonstrate the DSeg function. } + +Var + W : Word; + +begin + W:=DSeg; {W:=0, This function is provided for compatibility, + FPC is a 32 bit comiler.} +end. diff --git a/docs/refex/ex18.pp b/docs/refex/ex18.pp new file mode 100644 index 0000000000..14c63ac82d --- /dev/null +++ b/docs/refex/ex18.pp @@ -0,0 +1,22 @@ +Program Example18; + +{ Program to demonstrate the Eof function. } + +Var T1,T2 : text; + C : Char; + +begin + { Set file to read from. Empty means from standard input.} + assign (t1,paramstr(1)); + reset (t1); + { Set file to write to. Empty means to standard output. } + assign (t2,paramstr(2)); + rewrite (t2); + While not eof(t1) do + begin + read (t1,C); + write (t2,C); + end; + Close (t1); + Close (t2); +end. diff --git a/docs/refex/ex19.pp b/docs/refex/ex19.pp new file mode 100644 index 0000000000..e8fb16fb04 --- /dev/null +++ b/docs/refex/ex19.pp @@ -0,0 +1,11 @@ +Program Example19; + +{ Program to demonstrate the Eoln function. } + +begin + { This program waits for keyboard input. } + { It will print True when an empty line is put in, + and false when you type a non-empty line. + It will only stop when you press enter.} + Writeln (eoln); +end. diff --git a/docs/refex/ex2.pp b/docs/refex/ex2.pp new file mode 100644 index 0000000000..843775f89c --- /dev/null +++ b/docs/refex/ex2.pp @@ -0,0 +1,14 @@ +Program Example2; + +{ Program to demonstrate the Addr function. } + +Const Zero : integer = 0; + +Var p : pointer; + i : Integer; + +begin + p:=Addr(p); { P points to itself } + p:=Addr(I); { P points to I } + p:=Addr(Zero); { P points to 'Zero' } +end. diff --git a/docs/refex/ex20.pp b/docs/refex/ex20.pp new file mode 100644 index 0000000000..eaffc76c82 --- /dev/null +++ b/docs/refex/ex20.pp @@ -0,0 +1,15 @@ +Program Example20; + +{ Program to demonstrate the Erase function. } + +Var F : Text; + +begin + { Create a file with a line of text in it} + Assign (F,'test.txt'); + Rewrite (F); + Writeln (F,'Try and find this when I''m finished !'); + close (f); + { Now remove the file } + Erase (f); +end. diff --git a/docs/refex/ex21.pp b/docs/refex/ex21.pp new file mode 100644 index 0000000000..01892e2866 --- /dev/null +++ b/docs/refex/ex21.pp @@ -0,0 +1,40 @@ +Program Example21; + +{ Program to demonstrate the Exit function. } + +Procedure DoAnExit (Yes : Boolean); + +{ This procedure demonstrates the normal Exit } + +begin + Writeln ('Hello from DoAnExit !'); + If Yes then + begin + Writeln ('Bailing out early.'); + exit; + end; + Writeln ('Continuing to the end.'); +end; + +Function Positive (Which : Integer) : Boolean; + +{ This function demonstrates the extra FPC feature of Exit : + You can specify a return value for the function } + +begin + if Which>0 then + exit (True) + else + exit (False); +end; + +begin + { This call will go to the end } + DoAnExit (False); + { This call will bail out early } + DoAnExit (True); + if Positive (-1) then + Writeln ('The compiler is nuts, -1 is not positive.') + else + Writeln ('The compiler is not so bad, -1 seems to be negative.'); +end. diff --git a/docs/refex/ex22.pp b/docs/refex/ex22.pp new file mode 100644 index 0000000000..0de49adba4 --- /dev/null +++ b/docs/refex/ex22.pp @@ -0,0 +1,7 @@ +Program Example22; + +{ Program to demonstrate the Exp function. } + +begin + Writeln (Exp(1):8:2); { Should print 2.72 } +end. diff --git a/docs/refex/ex23.pp b/docs/refex/ex23.pp new file mode 100644 index 0000000000..ebe964df83 --- /dev/null +++ b/docs/refex/ex23.pp @@ -0,0 +1,30 @@ +Program Example23; + +{ Program to demonstrate the FilePos function. } + +Var F : File of Longint; + L,FP : longint; + +begin + { Fill a file with data : + Each position contains the position ! } + Assign (F,'test.dat'); + Rewrite (F); + For L:=0 to 100 do + begin + FP:=FilePos(F); + Write (F,FP); + end; + Close (F); + Reset (F); + { If ll goes well, nothing is displayed here. } + While not (Eof(F)) do + begin + FP:=FilePos (F); + Read (F,L); + if L<>FP then + Writeln ('Something is wrong here ! : Got ',l,' on pos ',FP); + end; + Close (F); + Erase (f); +end. diff --git a/docs/refex/ex24.pp b/docs/refex/ex24.pp new file mode 100644 index 0000000000..a98400cafb --- /dev/null +++ b/docs/refex/ex24.pp @@ -0,0 +1,18 @@ +Program Example24; + +{ Program to demonstrate the FileSize function. } + +Var F : File Of byte; + L : File Of Longint; + +begin + Assign (F,paramstr(1)); + Reset (F); + Writeln ('File size in bytes : ',FileSize(F)); + Close (F); + Assign (L,paramstr (1)); + Reset (L); + Writeln ('File size in Longints : ',FileSize(L)); + Close (f); +end. + diff --git a/docs/refex/ex25.pp b/docs/refex/ex25.pp new file mode 100644 index 0000000000..68f264ee87 --- /dev/null +++ b/docs/refex/ex25.pp @@ -0,0 +1,16 @@ +Program Example25; + +{ Program to demonstrate the FillChar function. } + +Var S : String[10]; + I : Byte; +begin + For i:=10 downto 0 do + begin + { Fill S with i spaces } + FillChar (S,SizeOf(S),' '); + { Set Length } + S[0]:=chr(i); + Writeln (s,'*'); + end; +end. diff --git a/docs/refex/ex26.pp b/docs/refex/ex26.pp new file mode 100644 index 0000000000..e474460606 --- /dev/null +++ b/docs/refex/ex26.pp @@ -0,0 +1,22 @@ +Program Example26; + +{ Program to demonstrate the Flush function. } + +Var F : Text; + +begin + { Assign F to standard output } + Assign (F,''); + Rewrite (F); + Writeln (F,'This line is written first, but appears later !'); + { At this point the text is in the internal pascal buffer, + and not yet written to standard output } + Writeln ('This line appears first, but is written later !'); + { A writeln to 'output' always causes a flush - so this text is + written to screen } + Flush (f); + { At this point, the text written to F is written to screen. } + Write (F,'Finishing '); + Close (f); { Closing a file always causes a flush first } + Writeln ('off.'); +end. diff --git a/docs/refex/ex27.pp b/docs/refex/ex27.pp new file mode 100644 index 0000000000..58d287aa6d --- /dev/null +++ b/docs/refex/ex27.pp @@ -0,0 +1,10 @@ +Program Example27; + +{ Program to demonstrate the Frac function. } + +Var R : Real; + +begin + Writeln (Frac (123.456):0:3); { Prints O.456 } + Writeln (Frac (-123.456):0:3); { Prints -O.456 } +end. diff --git a/docs/refex/ex28.pp b/docs/refex/ex28.pp new file mode 100644 index 0000000000..964eb1de9e --- /dev/null +++ b/docs/refex/ex28.pp @@ -0,0 +1,21 @@ +Program Example28; + +{ Program to demonstrate the FreeMem and GetMem functions. } + +Var P : Pointer; + MM : Longint; + +begin + { Get memory for P } + MM:=MemAvail; + Writeln ('Memory available before GetMem : ',MemAvail); + GetMem (P,80); + MM:=MM-Memavail; + Write ('Memory available after GetMem : ',MemAvail); + Writeln (' or ',MM,' bytes less than before the call.'); + { fill it with spaces } + FillChar (P^,80,' '); + { Free the memory again } + FreeMem (P,80); + Writeln ('Memory available after FreeMem : ',MemAvail); +end. diff --git a/docs/refex/ex29.pp b/docs/refex/ex29.pp new file mode 100644 index 0000000000..db0148fce3 --- /dev/null +++ b/docs/refex/ex29.pp @@ -0,0 +1,10 @@ +Program Example29; + +{ Program to demonstrate the GetDir function. } + +Var S : String; + +begin + GetDir (0,S); + Writeln ('Current directory is : ',S); +end. diff --git a/docs/refex/ex3.pp b/docs/refex/ex3.pp new file mode 100644 index 0000000000..2c378db355 --- /dev/null +++ b/docs/refex/ex3.pp @@ -0,0 +1,16 @@ +Program Example3; + +{ Program to demonstrate the Append function. } + +Var f : text; + +begin + Assign (f,'test.txt'); + Rewrite (f); { file is opened for write, and emptied } + Writeln (F,'This is the first line of text.txt'); + close (f); + Append(f); { file is opened for write, but NOT emptied. + any text written to it is appended.} + Writeln (f,'This is the second line of text.txt'); + close (f); +end. diff --git a/docs/refex/ex30.pp b/docs/refex/ex30.pp new file mode 100644 index 0000000000..f53301aa0a --- /dev/null +++ b/docs/refex/ex30.pp @@ -0,0 +1,9 @@ +Program Example30; + +{ Program to demonstrate the Halt function. } + +begin + Writeln ('Before Halt.'); + Halt (1); { Stop with exit code 1 } + Writeln ('After Halt doesn''t get executed.'); +end. diff --git a/docs/refex/ex31.pp b/docs/refex/ex31.pp new file mode 100644 index 0000000000..c5f7401759 --- /dev/null +++ b/docs/refex/ex31.pp @@ -0,0 +1,14 @@ +Program Example31; + +{ Program to demonstrate the Hi function. } + +var + L : Longint; + W : Word; + +begin + L:=1 Shl 16; { = $10000 } + W:=1 Shl 8; { = $100 } + Writeln (Hi(L)); { Prints 1 } + Writeln (Hi(W)); { Prints 1 } +end. diff --git a/docs/refex/ex32.pp b/docs/refex/ex32.pp new file mode 100644 index 0000000000..feb32d2505 --- /dev/null +++ b/docs/refex/ex32.pp @@ -0,0 +1,23 @@ +Program Example32; + +{ Program to demonstrate the Inc function. } + +Const + C : Cardinal = 1; + L : Longint = 1; + I : Integer = 1; + W : Word = 1; + B : Byte = 1; + SI : ShortInt = 1; + CH : Char = 'A'; + +begin + Inc (C); { C:=2 } + Inc (L,5); { L:=6 } + Inc (I,-3); { I:=-2 } + Inc (W,3); { W:=4 } + Inc (B,100); { B:=101 } + Inc (SI,-3); { Si:=-2 } + Inc (CH,1); { ch:='B' } +end. + diff --git a/docs/refex/ex33.pp b/docs/refex/ex33.pp new file mode 100644 index 0000000000..6bdb85db99 --- /dev/null +++ b/docs/refex/ex33.pp @@ -0,0 +1,11 @@ +Program Example33; + +{ Program to demonstrate the Insert function. } + +Var S : String; + +begin + S:='Free Pascal is difficult to use !'; + Insert ('NOT ',S,pos('difficult',S)); + writeln (s); +end. diff --git a/docs/refex/ex34.pp b/docs/refex/ex34.pp new file mode 100644 index 0000000000..d14757db53 --- /dev/null +++ b/docs/refex/ex34.pp @@ -0,0 +1,8 @@ +Program Example34; + +{ Program to demonstrate the Int function. } + +begin + Writeln (Int(123.456):0:1); { Prints 123.0 } + Writeln (Int(-123.456):0:1); { Prints -123.0 } +end. diff --git a/docs/refex/ex35.pp b/docs/refex/ex35.pp new file mode 100644 index 0000000000..6a537ad6cb --- /dev/null +++ b/docs/refex/ex35.pp @@ -0,0 +1,16 @@ +Program Example35; + +{ Program to demonstrate the IOResult function. } + +Var F : text; + +begin + Assign (f,paramstr(1)); + {$i-} + Reset (f); + {$i+} + If IOresult<>0 then + writeln ('File ',paramstr(1),' doesn''t exist') + else + writeln ('File ',paramstr(1),' exists'); +end. diff --git a/docs/refex/ex36.pp b/docs/refex/ex36.pp new file mode 100644 index 0000000000..1c64fca33f --- /dev/null +++ b/docs/refex/ex36.pp @@ -0,0 +1,15 @@ +Program Example36; + +{ Program to demonstrate the Length function. } + +Var S : String; + I : Integer; + +begin + S:=''; + for i:=1 to 10 do + begin + S:=S+'*'; + Writeln (Length(S):2,' : ',s); + end; +end. diff --git a/docs/refex/ex37.pp b/docs/refex/ex37.pp new file mode 100644 index 0000000000..bac21baef8 --- /dev/null +++ b/docs/refex/ex37.pp @@ -0,0 +1,8 @@ +Program Example37; + +{ Program to demonstrate the Ln function. } + +begin + Writeln (Ln(1)); { Prints 0 } + Writeln (Ln(Exp(1))); { Prints 1 } +end. diff --git a/docs/refex/ex38.pp b/docs/refex/ex38.pp new file mode 100644 index 0000000000..920254151b --- /dev/null +++ b/docs/refex/ex38.pp @@ -0,0 +1,13 @@ +Program Example38; + +{ Program to demonstrate the Lo function. } + +Var L : Longint; + W : Word; + +begin + L:=(1 Shl 16) + (1 Shl 4); { $10010 } + Writeln (Lo(L)); { Prints 16 } + W:=(1 Shl 8) + (1 Shl 4); { $110 } + Writeln (Lo(W)); { Prints 16 } +end. diff --git a/docs/refex/ex39.pp b/docs/refex/ex39.pp new file mode 100644 index 0000000000..dc8be07a8f --- /dev/null +++ b/docs/refex/ex39.pp @@ -0,0 +1,18 @@ +Program Example39; + +{ Program to demonstrate the Mark and Release functions. } + +Var P,PP,PPP,MM : Pointer; + +begin + Getmem (P,100); + Mark (MM); + Writeln ('Getmem 100 : Memory available : ',MemAvail,' (marked)'); + GetMem (PP,1000); + Writeln ('Getmem 1000 : Memory available : ',MemAvail); + GetMem (PPP,100000); + Writeln ('Getmem 10000 : Memory available : ',MemAvail); + Release (MM); + Writeln ('Released : Memory available : ',MemAvail); + { At this point, PP and PPP are invalid ! } +end. diff --git a/docs/refex/ex4.pp b/docs/refex/ex4.pp new file mode 100644 index 0000000000..0bff65f638 --- /dev/null +++ b/docs/refex/ex4.pp @@ -0,0 +1,10 @@ +Program Example4; + +{ Program to demonstrate the ArcTan function. } + +Var R : Real; + +begin + R:=ArcTan(0); { R:=0 } + R:=ArcTan(1)/pi; { R:=0.25 } +end. diff --git a/docs/refex/ex40.pp b/docs/refex/ex40.pp new file mode 100644 index 0000000000..e53f69e66c --- /dev/null +++ b/docs/refex/ex40.pp @@ -0,0 +1,22 @@ +Program Example40; + +{ Program to demonstrate the MaxAvail function. } + +Var + P : Pointer; + I : longint; + +begin + { This will allocate memory until there is no more memory} + I:=0; + While MaxAvail>=1000 do + begin + Inc (I); + GetMem (P,1000); + end; + { Default 4MB heap is allocated, so 4000 blocks + should be allocated. + When compiled with the -Ch10000 switch, the program + will be able to allocate 10 block } + Writeln ('Allocated ',i,' blocks of 1000 bytes'); +end. diff --git a/docs/refex/ex41.pp b/docs/refex/ex41.pp new file mode 100644 index 0000000000..dded8fb4b2 --- /dev/null +++ b/docs/refex/ex41.pp @@ -0,0 +1,17 @@ +Program Example41; + +{ Program to demonstrate the MemAvail function. } + +Var + P, PP : Pointer; + +begin + GetMem (P,100); + GetMem (PP,10000); + FreeMem (P,100); + { Due to the heap fragmentation introduced + By the previous calls, the maximum amount of memory + isn't equal to the maximum block size available. } + Writeln ('Total heap available (Bytes) : ',MemAvail); + Writeln ('Largest block available (Bytes) : ',MaxAvail); +end. diff --git a/docs/refex/ex42.pp b/docs/refex/ex42.pp new file mode 100644 index 0000000000..db47909de1 --- /dev/null +++ b/docs/refex/ex42.pp @@ -0,0 +1,12 @@ +Program Example42; + +{ Program to demonstrate the Move function. } + +Var S1,S2 : String [30]; + +begin + S1:='Hello World !'; + S2:='Bye, bye !'; + Move (S1,S2,Sizeof(S1)); + Writeln (S2); +end. diff --git a/docs/refex/ex43.pp b/docs/refex/ex43.pp new file mode 100644 index 0000000000..bda7487f29 --- /dev/null +++ b/docs/refex/ex43.pp @@ -0,0 +1,10 @@ +Program Example43; + +{ Program to demonstrate the Odd function. } + +begin + If Odd(1) Then + Writeln ('Everything OK with 1 !'); + If Not Odd(2) Then + Writeln ('Everything OK with 2 !'); +end. diff --git a/docs/refex/ex44.pp b/docs/refex/ex44.pp new file mode 100644 index 0000000000..79b3584448 --- /dev/null +++ b/docs/refex/ex44.pp @@ -0,0 +1,10 @@ +Program Example44; + +{ Program to demonstrate the Ofs function. } + +Var W : Pointer; + + +begin + W:=Ofs(W); { W contains its own offset. } +end. diff --git a/docs/refex/ex45.pp b/docs/refex/ex45.pp new file mode 100644 index 0000000000..76e013ec68 --- /dev/null +++ b/docs/refex/ex45.pp @@ -0,0 +1,17 @@ +Program Example45; + +{ Program to demonstrate the Ord function. } + +Type + TEnum = (Zero, One, Two, Three, Four); + +Var + X : Longint; + Y : TEnum; + +begin + X:=125; + Writeln (Ord(X)); { Prints 125 } + Y:= One; + Writeln (Ord(y)); { Prints 1 } +end. diff --git a/docs/refex/ex46.pp b/docs/refex/ex46.pp new file mode 100644 index 0000000000..24a424d333 --- /dev/null +++ b/docs/refex/ex46.pp @@ -0,0 +1,11 @@ +Program Example46; + +{ Program to demonstrate the ParamCount and ParamStr functions. } +Var + I : Longint; + +begin + Writeln (paramstr(0),' : Got ',ParamCount,' command-line parameters: '); + For i:=1 to ParamCount do + Writeln (ParamStr (i)); +end. diff --git a/docs/refex/ex47.pp b/docs/refex/ex47.pp new file mode 100644 index 0000000000..aa4c97201e --- /dev/null +++ b/docs/refex/ex47.pp @@ -0,0 +1,8 @@ +Program Example47; + +{ Program to demonstrate the Pi function. } + +begin + Writeln (Pi); {3.1415926} + Writeln (Sin(Pi)); +end. diff --git a/docs/refex/ex48.pp b/docs/refex/ex48.pp new file mode 100644 index 0000000000..d3f24d5788 --- /dev/null +++ b/docs/refex/ex48.pp @@ -0,0 +1,14 @@ +Program Example48; + +{ Program to demonstrate the Pos function. } + +Var + S : String; + +begin + S:='The first space in this sentence is at position : '; + Writeln (S,pos(' ',S)); + S:='The last letter of the alphabet doesn''t appear in this sentence '; + If (Pos ('Z',S)=0) and (Pos('z',S)=0) then + Writeln (S); +end. diff --git a/docs/refex/ex49.pp b/docs/refex/ex49.pp new file mode 100644 index 0000000000..8f09f36408 --- /dev/null +++ b/docs/refex/ex49.pp @@ -0,0 +1,24 @@ +Program Example49; + +{ Program to demonstrate the Random and Randomize functions. } + +Var I,Count,guess : Longint; + R : Real; + +begin + Randomize; { This way we generate a new sequence every time + the program is run} + Count:=0; + For i:=1 to 1000 do + If Random>0.5 then inc(Count); + Writeln ('Generated ',Count,' numbers > 0.5'); + Writeln ('out of 1000 generated numbers.'); + count:=0; + For i:=1 to 5 do + begin + write ('Guess a number between 1 and 5 : '); + readln(Guess); + If Guess=Random(5)+1 then inc(count); + end; + Writeln ('You guessed ',Count,' out of 5 correct.'); +end. diff --git a/docs/refex/ex5.pp b/docs/refex/ex5.pp new file mode 100644 index 0000000000..18d8fe9132 --- /dev/null +++ b/docs/refex/ex5.pp @@ -0,0 +1,18 @@ +Program Example5; + +{ Program to demonstrate the Assign function. } + +Var F : text; + +begin + Assign (F,''); + Rewrite (f); + { The following can be put in any file by redirecting it + from the command line.} + Writeln (f,'This goes to standard output !'); + Close (f); + Assign (F,'Test.txt'); + rewrite (f); + writeln (f,'This doesn''t go to standard output !'); + close (f); +end. diff --git a/docs/refex/ex50.pp b/docs/refex/ex50.pp new file mode 100644 index 0000000000..44c897a3f0 --- /dev/null +++ b/docs/refex/ex50.pp @@ -0,0 +1,25 @@ +Program Example50; + +{ Program to demonstrate the Read(Ln) function. } + +Var S : String; + C : Char; + F : File of char; + +begin + Assign (F,'ex50.pp'); + Reset (F); + C:='A'; + Writeln ('The characters before the first space in ex50.pp are : '); + While not Eof(f) and (C<>' ') do + Begin + Read (F,C); + Write (C); + end; + Writeln; + Close (F); + Writeln ('Type some words. An empty line ends the program.'); + repeat + Readln (S); + until S=''; +end. diff --git a/docs/refex/ex51.pp b/docs/refex/ex51.pp new file mode 100644 index 0000000000..0735bce367 --- /dev/null +++ b/docs/refex/ex51.pp @@ -0,0 +1,23 @@ +Program Example51; + +{ Program to demonstrate the Reset function. } + +Function FileExists (Name : String) : boolean; + +Var F : File; + +begin + {$i-} + Assign (F,Name); + Reset (F); + {$I+} + FileExists:=(IoResult=0) and (Name<>''); + Close (f); +end; + +begin + If FileExists (Paramstr(1)) then + Writeln ('File found') + else + Writeln ('File NOT found'); +end. diff --git a/docs/refex/ex52.pp b/docs/refex/ex52.pp new file mode 100644 index 0000000000..466a882562 --- /dev/null +++ b/docs/refex/ex52.pp @@ -0,0 +1,17 @@ +Program Example52; + +{ Program to demonstrate the Rewrite function. } + +Var F : File; + I : longint; + +begin + Assign (F,'Test.dat'); + { Create the file. Recordsize is 4 } + Rewrite (F,Sizeof(I)); + For I:=1 to 10 do + BlockWrite (F,I,1); + close (f); + { F contains now a binary representation of + 10 longints going from 1 to 10 } +end. diff --git a/docs/refex/ex53.pp b/docs/refex/ex53.pp new file mode 100644 index 0000000000..87b6ceff68 --- /dev/null +++ b/docs/refex/ex53.pp @@ -0,0 +1,20 @@ +Program Example53; + +{ Program to demonstrate the MkDir and RmDir functions. } + +Const D : String[8] = 'TEST.DIR'; + +Var S : String; + +begin + Writeln ('Making directory ',D); + Mkdir (D); + Writeln ('Changing directory to ',D); + ChDir (D); + GetDir (0,S); + Writeln ('Current Directory is : ',S); + WRiteln ('Going back'); + ChDir ('..'); + Writeln ('Removing directory ',D); + RmDir (D); +end. diff --git a/docs/refex/ex54.pp b/docs/refex/ex54.pp new file mode 100644 index 0000000000..bef31138a4 --- /dev/null +++ b/docs/refex/ex54.pp @@ -0,0 +1,10 @@ +Program Example54; + +{ Program to demonstrate the Round function. } + +begin + Writeln (Round(123.456)); { Prints 124 } + Writeln (Round(-123.456)); { Prints -124 } + Writeln (Round(12.3456)); { Prints 12 } + Writeln (Round(-12.3456)); { Prints -12 } +end. diff --git a/docs/refex/ex55.pp b/docs/refex/ex55.pp new file mode 100644 index 0000000000..88ade9b64c --- /dev/null +++ b/docs/refex/ex55.pp @@ -0,0 +1,8 @@ +Program Example55; + +{ Program to demonstrate the RunError function. } + +begin + { The program will stop end emit a run-error 106 } + RunError (106); +end. diff --git a/docs/refex/ex56.pp b/docs/refex/ex56.pp new file mode 100644 index 0000000000..6edbeaeabf --- /dev/null +++ b/docs/refex/ex56.pp @@ -0,0 +1,27 @@ +Program Example56; + +{ Program to demonstrate the Seek function. } + +Var + F : File; + I,j : longint; + +begin + { Create a file and fill it with data } + Assign (F,'test.dat'); + Rewrite(F); { Create file } + Close(f); + FileMode:=2; + ReSet (F,Sizeof(i)); { Opened read/write } + For I:=0 to 10 do + BlockWrite (F,I,1); + { Go Back to the begining of the file } + Seek(F,0); + For I:=0 to 10 do + begin + BlockRead (F,J,1); + If J<>I then + Writeln ('Error: expected ' ,i,', got ',j); + end; + Close (f); +end. diff --git a/docs/refex/ex57.pp b/docs/refex/ex57.pp new file mode 100644 index 0000000000..79dfb54757 --- /dev/null +++ b/docs/refex/ex57.pp @@ -0,0 +1,14 @@ +Program Example57; + +{ Program to demonstrate the SeekEof function. } +Var C : Char; + +begin + { this will print all characters from standard input except + Whitespace characters. } + While Not SeekEof do + begin + Read (C); + Write (C); + end; +end. diff --git a/docs/refex/ex58.pp b/docs/refex/ex58.pp new file mode 100644 index 0000000000..9c2d62a025 --- /dev/null +++ b/docs/refex/ex58.pp @@ -0,0 +1,15 @@ +Program Example58; + +{ Program to demonstrate the SeekEoln function. } +Var + C : Char; + +begin + { This will read the first line of standard output and print + all characters except whitespace. } + While not SeekEoln do + Begin + Read (c); + Write (c); + end; +end. diff --git a/docs/refex/ex59.pp b/docs/refex/ex59.pp new file mode 100644 index 0000000000..c442fd36b2 --- /dev/null +++ b/docs/refex/ex59.pp @@ -0,0 +1,13 @@ +Program Example59; + +{ Program to demonstrate the Ptr function. } + +Var P : ^String; + S : String; + +begin + S:='Hello, World !'; + P:=Ptr(Seg(S),Longint(Ofs(S))); + {P now points to S !} + Writeln (P^); +end. diff --git a/docs/refex/ex6.pp b/docs/refex/ex6.pp new file mode 100644 index 0000000000..7cceec548a --- /dev/null +++ b/docs/refex/ex6.pp @@ -0,0 +1,23 @@ +Program Example6; + +{ Program to demonstrate the BlockRead and BlockWrite functions. } + +Var Fin, fout : File; + NumRead,NumWritten : Word; + Buf : Array[1..2048] of byte; + Total : Longint; + +begin + Assign (Fin, Paramstr(1)); + Assign (Fout,Paramstr(2)); + Reset (Fin,1); + Rewrite (Fout,1); + Total:=0; + Repeat + BlockRead (Fin,buf,Sizeof(buf),NumRead); + BlockWrite (Fout,Buf,NumRead,NumWritten); + inc(Total,NumWritten); + Until (NumRead=0) or (NumWritten<>NumRead); + Write ('Copied ',Total,' bytes from file ',paramstr(1)); + Writeln (' to file ',paramstr(2)); +end. diff --git a/docs/refex/ex60.pp b/docs/refex/ex60.pp new file mode 100644 index 0000000000..6fba9d5e42 --- /dev/null +++ b/docs/refex/ex60.pp @@ -0,0 +1,9 @@ +Program Example60; + +{ Program to demonstrate the Seg function. } +Var + W : Word; + +begin + W:=Seg(W); { W contains its own Segment} +end. diff --git a/docs/refex/ex61.pp b/docs/refex/ex61.pp new file mode 100644 index 0000000000..32708c6283 --- /dev/null +++ b/docs/refex/ex61.pp @@ -0,0 +1,28 @@ +Program Example61; + +{ Program to demonstrate the SetTextBuf function. } + +Var + Fin,Fout : Text; + Ch : Char; + Bufin,Bufout : Array[1..10000] of byte; + +begin + Assign (Fin,paramstr(1)); + Reset (Fin); + Assign (Fout,paramstr(2)); + Rewrite (Fout); + { This is harmless before IO has begun } + { Try this program again on a big file, + after commenting out the following 2 + lines and recompiling it. } + SetTextBuf (Fin,Bufin); + SetTextBuf (Fout,Bufout); + While not eof(Fin) do + begin + Read (Fin,ch); + write (Fout,ch); + end; + Close (Fin); + Close (Fout); +end. diff --git a/docs/refex/ex62.pp b/docs/refex/ex62.pp new file mode 100644 index 0000000000..51db4637ee --- /dev/null +++ b/docs/refex/ex62.pp @@ -0,0 +1,8 @@ +Program Example62; + +{ Program to demonstrate the Sin function. } + +begin + Writeln (Sin(Pi):0:1); { Prints 0.0 } + Writeln (Sin(Pi/2):0:1); { Prints 1.0 } +end. diff --git a/docs/refex/ex63.pp b/docs/refex/ex63.pp new file mode 100644 index 0000000000..42982d8e5e --- /dev/null +++ b/docs/refex/ex63.pp @@ -0,0 +1,11 @@ +Program Example63; + +{ Program to demonstrate the SizeOf function. } +Var + I : Longint; + S : String [10]; + +begin + Writeln (SizeOf(I)); { Prints 4 } + Writeln (SizeOf(S)); { Prints 11 } +end. diff --git a/docs/refex/ex64.pp b/docs/refex/ex64.pp new file mode 100644 index 0000000000..4b3fd683af --- /dev/null +++ b/docs/refex/ex64.pp @@ -0,0 +1,9 @@ +Program Example64; + +{ Program to demonstrate the SPtr function. } +Var + P :Longint; + +begin + P:=Sptr; { P Contains now the current stack position. } +end. diff --git a/docs/refex/ex65.pp b/docs/refex/ex65.pp new file mode 100644 index 0000000000..6c6dcd89cc --- /dev/null +++ b/docs/refex/ex65.pp @@ -0,0 +1,9 @@ +Program Example65; + +{ Program to demonstrate the Sqr function. } +Var i : Integer; + +begin + For i:=1 to 10 do + writeln (Sqr(i):3); +end. diff --git a/docs/refex/ex66.pp b/docs/refex/ex66.pp new file mode 100644 index 0000000000..e35d11f909 --- /dev/null +++ b/docs/refex/ex66.pp @@ -0,0 +1,8 @@ +Program Example66; + +{ Program to demonstrate the Sqrt function. } + +begin + Writeln (Sqrt(4):0:3); { Prints 2.000 } + Writeln (Sqrt(2):0:3); { Prints 1.414 } +end. diff --git a/docs/refex/ex67.pp b/docs/refex/ex67.pp new file mode 100644 index 0000000000..b4663d0162 --- /dev/null +++ b/docs/refex/ex67.pp @@ -0,0 +1,8 @@ +Program Example67; + +{ Program to demonstrate the SSeg function. } +Var W : Longint; + +begin + W:=SSeg; +end. diff --git a/docs/refex/ex68.pp b/docs/refex/ex68.pp new file mode 100644 index 0000000000..3b95ba1d5e --- /dev/null +++ b/docs/refex/ex68.pp @@ -0,0 +1,18 @@ +Program Example68; + +{ Program to demonstrate the Str function. } +Var S : String; + +Function IntToStr (I : Longint) : String; + +Var S : String; + +begin + Str (I,S); + IntToStr:=S; +end; + +begin + S:='*'+IntToStr(-233)+'*'; + Writeln (S); +end. diff --git a/docs/refex/ex69.pp b/docs/refex/ex69.pp new file mode 100644 index 0000000000..97fab6ab51 --- /dev/null +++ b/docs/refex/ex69.pp @@ -0,0 +1,16 @@ +Program Example69; + +{ Program to demonstrate the Swap function. } +Var W : Word; + L : Longint; + +begin + W:=$1234; + W:=Swap(W); + if W<>$3412 then + writeln ('Error when swapping word !'); + L:=$12345678; + L:=Swap(L); + if L<>$56781234 then + writeln ('Error when swapping Longint !'); +end. diff --git a/docs/refex/ex7.pp b/docs/refex/ex7.pp new file mode 100644 index 0000000000..511a281ab2 --- /dev/null +++ b/docs/refex/ex7.pp @@ -0,0 +1,11 @@ +Program Example7; + +{ Program to demonstrate the ChDir function. } + +begin + {$I-} + ChDir (ParamStr(1)); + if IOresult<>0 then + Writeln ('Cannot change to directory : ',paramstr (1)); +end. + diff --git a/docs/refex/ex70.pp b/docs/refex/ex70.pp new file mode 100644 index 0000000000..2b74dd5392 --- /dev/null +++ b/docs/refex/ex70.pp @@ -0,0 +1,10 @@ +Program Example54; + +{ Program to demonstrate the Trunc function. } + +begin + Writeln (Trunc(123.456)); { Prints 123 } + Writeln (Trunc(-123.456)); { Prints -123 } + Writeln (Trunc(12.3456)); { Prints 12 } + Writeln (Trunc(-12.3456)); { Prints -12 } +end. diff --git a/docs/refex/ex71.pp b/docs/refex/ex71.pp new file mode 100644 index 0000000000..f70aabd0a3 --- /dev/null +++ b/docs/refex/ex71.pp @@ -0,0 +1,22 @@ +Program Example71; + +{ Program to demonstrate the Truncate function. } + +Var F : File of longint; + I,L : Longint; + +begin + Assign (F,'test.dat'); + Rewrite (F); + For I:=1 to 10 Do + Write (F,I); + Writeln ('Filesize before Truncate : ',FileSize(F)); + Close (f); + Reset (F); + Repeat + Read (F,I); + Until i=5; + Truncate (F); + Writeln ('Filesize after Truncate : ',Filesize(F)); + Close (f); +end. diff --git a/docs/refex/ex72.pp b/docs/refex/ex72.pp new file mode 100644 index 0000000000..5cd95cbb7c --- /dev/null +++ b/docs/refex/ex72.pp @@ -0,0 +1,13 @@ +Program Example72; + +{ Program to demonstrate the Upcase function. } + +Var I : Longint; + +begin + For i:=ord('a') to ord('z') do + write (upcase(chr(i))); + Writeln; + { This doesn't work in TP, but it does in Free Pascal } + Writeln (Upcase('abcdefghijklmnopqrstuvwxyz')); +end. diff --git a/docs/refex/ex73.pp b/docs/refex/ex73.pp new file mode 100644 index 0000000000..06fa588291 --- /dev/null +++ b/docs/refex/ex73.pp @@ -0,0 +1,12 @@ +Program Example73; + +{ Program to demonstrate the Lowercase function. } + +Var I : Longint; + +begin + For i:=ord('A') to ord('Z') do + write (lowercase(chr(i))); + Writeln; + Writeln (Lowercase('ABCDEFGHIJKLMNOPQRSTUVWXYZ')); +end. diff --git a/docs/refex/ex74.pp b/docs/refex/ex74.pp new file mode 100644 index 0000000000..6f8b893cdd --- /dev/null +++ b/docs/refex/ex74.pp @@ -0,0 +1,12 @@ +Program Example74; + +{ Program to demonstrate the Val function. } +Var I, Code : Integer; + +begin + Val (ParamStr (1),I,Code); + If Code<>0 then + Writeln ('Error at position ',code,' : ',Paramstr(1)[Code]) + else + Writeln ('Value : ',I); +end. diff --git a/docs/refex/ex75.pp b/docs/refex/ex75.pp new file mode 100644 index 0000000000..d93275e53e --- /dev/null +++ b/docs/refex/ex75.pp @@ -0,0 +1,18 @@ +Program Example75; + +{ Program to demonstrate the Write(ln) function. } + +Var + F : File of Longint; + L : Longint; + +begin + Write ('This is on the first line ! '); { No CR/LF pair! } + Writeln ('And this too...'); + Writeln ('But this is already on the second line...'); + Assign (f,'test.dat'); + Rewrite (f); + For L:=1 to 10 do + write (F,L); { No writeln allowed here ! } + Close (f); +end. diff --git a/docs/refex/ex76.pp b/docs/refex/ex76.pp new file mode 100644 index 0000000000..0c6748331f --- /dev/null +++ b/docs/refex/ex76.pp @@ -0,0 +1,10 @@ +Program Example76; + +{ Program to demonstrate the FillWord function. } + +Var W : Array[1..100] of Word; + +begin + { Quick initialization of array W } + FillWord(W,100,0); +end. diff --git a/docs/refex/ex77.pp b/docs/refex/ex77.pp new file mode 100644 index 0000000000..af82271128 --- /dev/null +++ b/docs/refex/ex77.pp @@ -0,0 +1,9 @@ +Program Example77; + +{ Program to demonstrate the Rename function. } +Var F : Text; + +begin + Assign (F,paramstr(1)); + Rename (F,paramstr(2)); +end. diff --git a/docs/refex/ex8.pp b/docs/refex/ex8.pp new file mode 100644 index 0000000000..e4cbf8dd75 --- /dev/null +++ b/docs/refex/ex8.pp @@ -0,0 +1,8 @@ +Program Example8; + +{ Program to demonstrate the Chr function. } + +begin + Write (chr(10),chr(13)); { The same effect as Writeln; } +end. + diff --git a/docs/refex/ex9.pp b/docs/refex/ex9.pp new file mode 100644 index 0000000000..fce2029a2f --- /dev/null +++ b/docs/refex/ex9.pp @@ -0,0 +1,15 @@ +Program Example9; + +{ Program to demonstrate the Close function. } + +Var F : text; + +begin + Assign (f,'Test.txt'); + ReWrite (F); + Writeln (F,'Some text written to Test.txt'); + close (f); { Flushes contents of buffer to disk, + closes the file. Omitting this may + cause data NOT to be written to disk.} +end. + diff --git a/docs/refex/foot.tex b/docs/refex/foot.tex new file mode 100644 index 0000000000..83788a402a --- /dev/null +++ b/docs/refex/foot.tex @@ -0,0 +1,2 @@ +\end{verbatim} +\end{FPKList} \ No newline at end of file diff --git a/docs/refex/head.tex b/docs/refex/head.tex new file mode 100644 index 0000000000..b2ed5b6603 --- /dev/null +++ b/docs/refex/head.tex @@ -0,0 +1,3 @@ +\begin{FPKList} +\item[Example] +\begin{verbatim} diff --git a/docs/refex/make1tex b/docs/refex/make1tex new file mode 100644 index 0000000000..0a14a89315 --- /dev/null +++ b/docs/refex/make1tex @@ -0,0 +1,10 @@ +#!/bin/csh +set texfile="all.tex" +echo '\documentclass{article}' >$texfile +echo '\usepackage{fpk}' >>$texfile +echo '\usepackage{a4}' >>$texfile +echo '\\begin{document}' >>$texfile +foreach f ( $* ) + echo "\input{$f}" >>$texfile +end +echo "\end{document}" >>$texfile diff --git a/docs/refex/newex b/docs/refex/newex new file mode 100644 index 0000000000..45f07f89e7 --- /dev/null +++ b/docs/refex/newex @@ -0,0 +1,8 @@ +#!/bin/sh +if [ -e ex${1}.pp ]; then + mv ex${1}.pp ex${1}.pp.orig +fi +sed -e s/Example/Example$1/ -e s/\\\*\\\*\\\*/$2/ ex${1}.pp +echo "ex${1}.pp contains an example of the $2 function." >>README +joe ex${1}.pp +ppc386 ex${1}.pp && ex${1} diff --git a/docs/refex/pp2tex b/docs/refex/pp2tex new file mode 100644 index 0000000000..3a5cd6a448 --- /dev/null +++ b/docs/refex/pp2tex @@ -0,0 +1,5 @@ +#!/bin/sh +# Simply paste a header and footer to the program. +cat head.tex > $1.tex +cat $1.pp >> $1.tex +cat foot.tex >> $1.tex diff --git a/docs/refex/pp2tex.bat b/docs/refex/pp2tex.bat new file mode 100644 index 0000000000..a7a48d7628 --- /dev/null +++ b/docs/refex/pp2tex.bat @@ -0,0 +1,6 @@ +@echo off +rem msdos batch file +rem Simply paste a header and footer to the program. +type head.tex > %1.tex +type %1.pp >> %1.tex +type foot.tex >> %1.tex diff --git a/docs/refex/template.pp b/docs/refex/template.pp new file mode 100644 index 0000000000..97ce675354 --- /dev/null +++ b/docs/refex/template.pp @@ -0,0 +1,6 @@ +Program Example; + +{ Program to demonstrate the *** function. } + +begin +end. diff --git a/docs/refpdf.tex b/docs/refpdf.tex new file mode 100644 index 0000000000..9ded75e0e0 --- /dev/null +++ b/docs/refpdf.tex @@ -0,0 +1,22 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\pdfoutput=1 +\input{ref.tex} \ No newline at end of file diff --git a/docs/sockets.tex b/docs/sockets.tex new file mode 100644 index 0000000000..55e64b8ae0 --- /dev/null +++ b/docs/sockets.tex @@ -0,0 +1,429 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\chapter{The SOCKETS unit.} +This chapter describes the SOCKETS unit for Free Pascal. +it was written for \linux by Micha\"el Van Canneyt. + +The chapter is divided in 2 sections: +\begin{itemize} +\item The first section lists types, constants and variables from the +interface part of the unit. +\item The second section describes the functions defined in the unit. +\end{itemize} + +\section {Types, Constants and variables : } +The following constants identify the different socket types, as needed in +the \seef{Socket} call. +\begin{verbatim} +SOCK_STREAM = 1; { stream (connection) socket } +SOCK_DGRAM = 2; { datagram (conn.less) socket } +SOCK_RAW = 3; { raw socket } +SOCK_RDM = 4; { reliably-delivered message } +SOCK_SEQPACKET = 5; { sequential packet socket } +SOCK_PACKET =10; +\end{verbatim} +The following constants determine the socket domain, they are used in the +\seef{Socket} call. +\begin{verbatim} +AF_UNSPEC = 0; +AF_UNIX = 1; { Unix domain sockets } +AF_INET = 2; { Internet IP Protocol } +AF_AX25 = 3; { Amateur Radio AX.25 } +AF_IPX = 4; { Novell IPX } +AF_APPLETALK = 5; { Appletalk DDP } +AF_NETROM = 6; { Amateur radio NetROM } +AF_BRIDGE = 7; { Multiprotocol bridge } +AF_AAL5 = 8; { Reserved for Werner's ATM } +AF_X25 = 9; { Reserved for X.25 project } +AF_INET6 = 10; { IP version 6 } +AF_MAX = 12; +\end{verbatim} +The following constants determine the protocol family, they are used in the +\seef{Socket} call. +\begin{verbatim} +PF_UNSPEC = AF_UNSPEC; +PF_UNIX = AF_UNIX; +PF_INET = AF_INET; +PF_AX25 = AF_AX25; +PF_IPX = AF_IPX; +PF_APPLETALK = AF_APPLETALK; +PF_NETROM = AF_NETROM; +PF_BRIDGE = AF_BRIDGE; +PF_AAL5 = AF_AAL5; +PF_X25 = AF_X25; +PF_INET6 = AF_INET6; +PF_MAX = AF_MAX; +\end{verbatim} +The following types are used to store different kinds of eddresses for the +\seef{Bind}, \seef{Recv} and \seef{Send} calls. +\begin{verbatim} +TSockAddr = packed Record + family:word; + data :array [0..13] of char; + end; + +TUnixSockAddr = packed Record + family:word; + path:array[0..108] of char; + end; + +TInetSockAddr = packed Record + family:Word; + port :Word; + addr :Cardinal; + pad :array [1..8] of byte; + end; +\end{verbatim} +The following type is returned by the \seef{SocketPair} call. +\begin{verbatim} +TSockArray = Array[1..2] of Longint; +\end{verbatim} + +\section {Functions and Procedures} + +\function{Socket}{(Domain,SocketType,Protocol:Longint)}{Longint} +{\var{Socket} creates a new socket in domain \var{Domain}, from type +\var{SocketType} using protocol \var{Protocol}. + +The Domain, Socket type and Protocol can be specified using predefined +constants (see the section on constants for available constants) + +If succesfull, the function returns a socket descriptor, which can be passed +to a subsequent \seef{Bind} call. If unsuccesfull, the function returns -1. +} +{Errors are returned in \var{SocketError}, and include the follwing: +\begin{description} +\item[SYS\_EPROTONOSUPPORT] +The protocol type or the specified protocol is not +supported within this domain. +\item[SYS\_EMFILE] +The per-process descriptor table is full. +\item[SYS\_ENFILE] +The system file table is full. +\item[SYS\_EACCESS] + Permission to create a socket of the specified + type and/or protocol is denied. +\item[SYS\_ENOBUFS] + Insufficient buffer space is available. The + socket cannot be created until sufficient + resources are freed. +\end{description}} +{\seef{SocketPair}, \seem{socket}{2}} +for an example, see \seef{Accept}. +\function{Send}{(Sock:Longint;Var Addr;AddrLen,Flags:Longint)}{Longint} +{\var{Send} sends \var{AddrLen} bytes starting from address \var{Addr} +to socket \var{Sock}. \var{Sock} must be in a connected state. + +The function returns the number of bytes sent, or -1 if a detectable +error occurred. + +\var{Flags} can be one of the following: +\begin{description} +\item [1] : Process out-of band data. +\item [4] : Bypass routing, use a direct interface. +\end{description} +} +{Errors are reported in \var{SocketError}, and include the following: +\begin{description} +\item[SYS\_EBADF] The socket descriptor is invalid. +\item[SYS\_ENOTSOCK] The descriptor is not a socket. +\item[SYS\_EFAULT] The address is outside your address space. +\item[SYS\_EMSGSIZE] The message cannot be sent atomically. +\item[SYS\_EWOULDBLOCK] The requested operation would block the process. +\item[SYS\_ENOBUFS] The system doesn't have enough free buffers available. +\end{description} +}{\seef{Recv}, \seem{send}{2}} + +\function{Recv}{(Sock:Longint;Var Addr;AddrLen,Flags:Longint)}{Longint} +{\var{Recv} reads at most \var{Addrlen} bytes from socket \var{Sock} into +address \var{Addr}. The socket must be in a connected state. + +\var{Flags} can be one of the following: +\begin{description} +\item [1] : Process out-of band data. +\item [4] : Bypass routing, use a direct interface. +\item [??] : Wait for full request or report an error. +\end{description} + +The functions returns the number of bytes actually read from the socket, or +-1 if a detectable error occurred.} +{Errors are reported in \var{SocketError}, and include the following: +\begin{description} +\item[SYS\_EBADF] The socket descriptor is invalid. +\item[SYS\_ENOTCONN] The socket isn't connected. +\item[SYS\_ENOTSOCK] The descriptor is not a socket. +\item[SYS\_EFAULT] The address is outside your address space. +\item[SYS\_EMSGSIZE] The message cannot be sent atomically. +\item[SYS\_EWOULDBLOCK] The requested operation would block the process. +\item[SYS\_ENOBUFS] The system doesn't have enough free buffers available. +\end{description} +}{\seef{Send}} + +\function{Bind}{(Sock:Longint;Var Addr;AddrLen:Longint)}{Boolean} +{\var{Bind} binds the socket \var{Sock} to address \var{Addr}. \var{Addr} +has length \var{Addrlen}. + +The function returns \var{True} if the call was succesful, \var{False} if +not. +} +{Errors are returned in \var{SocketError} and include the following: +\begin{description} +\item[SYS\_EBADF] The socket descriptor is invalid. +\item[SYS\_EINVAL] The socket is already bound to an address, +\item[SYS\_EACCESS] Address is protected and you don't have permission to +open it. +\end{description} +More arrors can be found in the Unix man pages. +}{\seef{Socket}} + +\functionl{Bind}{AltBind}{(Sock:longint;const addr:string)}{boolean} +{This is an alternate form of the \var{Bind} command. +This form of the \var{Bind} command is equivalent to subsequently +calling \seep{Str2UnixSockAddr} and the regular \seef{Bind} function. + +The function returns \var{True} if successfull, \var{False} otherwise. +} +{Errors are those of the regular \seef{Bind} command.} +{\seef{Bind}} + + +\function{Listen}{(Sock,MaxConnect:Longint)}{Boolean} +{\var{Listen} listens for up to \var{MaxConnect} connections from socket +\var{Sock}. The socket \var{Sock} must be of type \var{SOCK\_STREAM} or +\var{Sock\_SEQPACKET}. + +The function returns \var{True} if a connection was accepted, \var{False} +if an error occurred. +} +{Errors are reported in \var{SocketError}, and include the following: +\begin{description} +\item[SYS\_EBADF] The socket descriptor is invalid. +\item[SYS\_ENOTSOCK] The descriptor is not a socket. +\item[SYS\_EOPNOTSUPP] The socket type doesn't support the \var{Listen} +operation. +\end{description} +}{\seef{Socket}, \seef{Bind}, \seef{Connect}} + +\function{Accept}{(Sock:Longint;Var Addr;Var Addrlen:Longint)}{Longint} +{\var{Accept} accepts a connection from a socket \var{Sock}, which was +listening for a connection. The accepted socket may NOT be used to accept +more connections. The original socket remains open. + +The \var{Accept} call fills the address of the connecting entity in \var{Addr}, +and sets its length in \var{Addrlen}. \var{Addr} should be pointing to +enough space, and \var{Addrlen} should be set to the amount of space +available, prior to the call. +} +{Errors are reported in \var{SocketError}, and include the following: +\begin{description} +\item[SYS\_EBADF] The socket descriptor is invalid. +\item[SYS\_ENOTSOCK] The descriptor is not a socket. +\item[SYS\_EOPNOTSUPP] The socket type doesn't support the \var{Listen} +operation. +\item[SYS\_EFAULT] \var{Addr} points outside your address space. +\item[SYS\_EWOULDBLOCK] The requested operation would block the process. +\end{description} +} +{\seef{Listen}, \seef{Connect}} + +\input{sockex/sock_svr.tex} + +\functionl{Accept}{AltAAccept}{(Sock:longint;var addr:string;var SockIn,SockOut:text)}{Boolean} +{ This is an alternate form of the \seef{Accept} command. It is equivalent +to subsequently calling the regular \seef{Accept} +function and the \seep{Sock2Text} function. + +The function returns \var{True} if successfull, \var{False} otherwise. +} +{The errors are those of \seef{Accept}.} +{\seef{Accept}} + +\functionl{Accept}{AltBAccept}{(Sock:longint;var addr:string;var SockIn,SockOut:File)}{Boolean} +{ This is an alternate form of the \seef{Accept} command. +It is equivalent +to subsequently calling the regular \seef{Accept} function and the +\seep{Sock2File} function. + +The function returns \var{True} if successfull, \var{False} otherwise. +} +{The errors are those of \seef{Accept}.} +{\seef{Accept}} + + +\function{Connect}{(Sock:Longint;Var Addr;Addrlen:Longint)}{Boolean} +{\var{Connect} opens a connection to a peer, whose address is described by +var{Addr}. \var{AddrLen} contains the length of the address. + +The type of \var{Addr} depends on the kind of connection you're trying to +make, but is generally one of \var{TSockAddr} or \var{TUnixSockAddr}. +} +{Errors are reported in \var{SocketError}.} +{\seef{Listen}, \seef{Bind},\seef{Accept}} + +\input{sockex/sock_cli.tex} + +\functionl{Connect}{AltAConnect}{(Sock:longint;const addr:string;var SockIn,SockOut:text)}{Boolean} +{ This is an alternate form of the \seef{Connect} command. +It is equivalent +to subsequently calling the regular \seef{Connect} function and the +\seep{Sock2Text} function. + +The function returns \var{True} if successfull, \var{False} otherwise. +}{The errors are those of \seef{Connect}.} +{\seef{Connect}} + +\functionl{Connect}{AltBConnect}{(Sock:longint;const addr:string;var SockIn,SockOut:file)}{Boolean} +{ This is an alternate form of the \seef{Connect} command. +It is equivalent +to subsequently calling the regular \seef{Connect} function and the +\seep{Sock2File} function. + +The function returns \var{True} if successfull, \var{False} otherwise. +}{The errors are those of \seef{Connect}.} +{\seef{Connect}} + + +\function{Shutdown}{(Sock:Longint;How:Longint)}{Longint} +{\var{ShutDown} closes one end of a full duplex socket connection, described +by \var{Sock}. \var{How} determines how the connection will be shut down, +and can be one of the following: +\begin{description} +\item[0] : Further receives are disallowed. +\item[1] : Further sends are disallowed. +\item[2] : Sending nor receiving are allowed. +\end{description} + +On succes, the function returns 0, on error -1 is returned. +} +{\var{SocketError} is used to report errors, and includes the following: +\begin{description} +\item[SYS\_EBADF] The socket descriptor is invalid. +\item[SYS\_ENOTCONN] The socket isn't connected. +\item[SYS\_ENOTSOCK] The descriptor is not a socket. +\end{description} +}{\seef{Socket}, \seef{Connect}} + +\function{GetSocketName}{(Sock:Longint;Var Addr;Var Addrlen:Longint)}{Longint} +{\var{GetSockName} returns the current name of the specified socket +\var{Sock}. \var{Addr} should point to enough space to store the name, the +amount of space pointed to should be set in \var{Addrlen}. +When the function returns succesfully, \var{Addr} will be filled with the +name, and \var{Addrlen} will be set to the length of \var{Addr}.} +{Errors are reported in \var{SocketError}, and include the following: +\begin{description} +\item[SYS\_EBADF] The socket descriptor is invalid. +\item[SYS\_ENOBUFS] The system doesn't have enough buffers to perform the +operation. +\item[SYS\_ENOTSOCK] The descriptor is not a socket. +\item[SYS\_EFAULT] \var{Addr} points outside your address space. +\end{description} +}{\seef{Bind}} + +\function{GetPeerName}{(Sock:Longint;Var Addr;Var Addrlen:Longint)}{Longint} +{\var{GetPeerName} returns the name of the entity connected to the +specified socket \var{Sock}. The Socket must be connected for this call to +work. +\var{Addr} should point to enough space to store the name, the +amount of space pointed to should be set in \var{Addrlen}. +When the function returns succesfully, \var{Addr} will be filled with the +name, and \var{Addrlen} will be set to the length of \var{Addr}. +} +{Errors are reported in \var{SocketError}, and include the following: +\begin{description} +\item[SYS\_EBADF] The socket descriptor is invalid. +\item[SYS\_ENOBUFS] The system doesn't have enough buffers to perform the +operation. +\item[SYS\_ENOTSOCK] The descriptor is not a socket. +\item[SYS\_EFAULT] \var{Addr} points outside your address space. +\item[SYS\_ENOTCONN] The socket isn't connected. +\end{description} +}{\seef{Connect}, \seef{Socket}, \seem{connect}{2}} + +\function{SetSocketOptions}{(Sock,Level,OptName:Longint;Var OptVal;optlen:longint)}{Longint} +{\var{SetSocketOptions} sets the connection options for socket \var{Sock}. +The socket may be manipulated at different levels, indicated by \var{Level}, +which can be one of the following: +\begin{description} +\item[SOL\_SOCKET] To manipulate the socket itself. +\item[XXX] set \var{Level} to \var{XXX}, the protocol number of the protocol +which should interprete the option. + \end{description} +For more information on this call, refer to the unix manual page \seem{setsockopt}{2}. +} +{Errors are reported in \var{SocketError}, and include the following: +\begin{description} +\item[SYS\_EBADF] The socket descriptor is invalid. +\item[SYS\_ENOTSOCK] The descriptor is not a socket. +\item[SYS\_EFAULT] \var{OptVal} points outside your address space. +\end{description} +} +{\seef{GetSocketOptions}} + +\function{GetSocketOptions}{(Sock,Level,OptName:Longint;Var OptVal;optlen:longint)}{Longint} +{\var{GetSocketOptions} gets the connection options for socket \var{Sock}. +The socket may be obtained from different levels, indicated by \var{Level}, +which can be one of the following: +\begin{description} +\item[SOL\_SOCKET] From the socket itself. +\item[XXX] set \var{Level} to \var{XXX}, the protocol number of the protocol +which should interprete the option. + \end{description} +For more information on this call, refer to the unix manual page \seem{getsockopt}{2}. +} +{Errors are reported in \var{SocketError}, and include the following: +\begin{description} +\item[SYS\_EBADF] The socket descriptor is invalid. +\item[SYS\_ENOTSOCK] The descriptor is not a socket. +\item[SYS\_EFAULT] \var{OptVal} points outside your address space. +\end{description} +} +{\seef{GetSocketOptions}} + +\function{SocketPair}{(Domain,SocketType,Protocol:Longint;var Pair:TSockArray)}{Longint} +{\var{SocketPair} creates 2 sockets in domain \var{Domain}, from type +\var{SocketType} and using protocol \var{Protocol}. + +The pair is returned in \var{Pair}, and they are indistinguishable. + +The function returns -1 upon error and 0 upon success. +} +{Errors are reported in \var{SocketError}, and are the same as in \seef{Socket}} + +\procedure{Sock2Text}{(Sock:Longint;Var SockIn,SockOut: Text)} +{\var{Sock2Text} transforms a socket \var{Sock} into 2 Pascal file +descriptors of type \var{Text}, one for reading from the socket +(\var{SockIn}), one for writing to the socket (\var{SockOut}).} +{None.} +{\seef{Socket}, \seep{Sock2File}} + +\procedure{Sock2File}{(Sock:Longint;Var SockIn,SockOut:File)} +{\var{Sock2File} transforms a socket \var{Sock} into 2 Pascal file +descriptors of type \var{File}, one for reading from the socket +(\var{SockIn}), one for writing to the socket (\var{SockOut}).} +{None.} +{\seef{Socket}, \seep{Sock2Text}} + +\procedure{Str2UnixSockAddr}{(const addr:string;var t:TUnixSockAddr;var len:longint)} +{\var{Str2UnixSockAddr} transforms a Unix socket address in a string to a +\var{TUnixSockAddr} sturcture which can be passed to the \seef{Bind} call. +} +{None.} +{\seef{Socket}, \seef{Bind}} diff --git a/docs/sockex/Makefile b/docs/sockex/Makefile new file mode 100644 index 0000000000..567f537490 --- /dev/null +++ b/docs/sockex/Makefile @@ -0,0 +1,53 @@ +####################################################################### +# +# Makefile to compile all examples and convert them to LaTeX +# +####################################################################### + +# Compiler +PP=ppc386 + +# Unit directory +# UNITDIR=/usr/lib/ppc/0.99.0/linuxunits + + +# Any options you wish to pass. +PPOPTS= + +# Script to convert the programs to LaTeX examples which can be included. +PP2TEX=pp2tex + +# Script to collect all examples in 1 file. +MAKETEX=make1tex + +####################################################################### +# No need to edit after this line. +####################################################################### + +ifdef UNITDIR +PPOPTS:=$(PPOPTS) -Up$(UNITDIR); +endif + +.SUFFIXES: .pp .tex + +.PHONY: all tex clean + +OBJECTS=sock_cli sock_svr + +TEXOBJECTS=$(addsuffix .tex, $(OBJECTS)) + +all : $(OBJECTS) + +tex : $(TEXOBJECTS) + +onetex : tex + $(MAKETEX) $(TEXOBJECTS) + +clean : + rm -f *.o *.s $(OBJECTS) $(TEXOBJECTS) + +$(OBJECTS): %: %.pp + $(PP) $(PPOPTS) $* + +$(TEXOBJECTS): %.tex: %.pp head.tex foot.tex + $(PP2TEX) $* diff --git a/docs/sockex/README b/docs/sockex/README new file mode 100644 index 0000000000..e8b68f73d5 --- /dev/null +++ b/docs/sockex/README @@ -0,0 +1,7 @@ +These are the example programs that appear in the FPC documentation. + +Units guide, chapter on Sockets unit : + +Example programs +sock_svr.pp implements a small server application. +sock_cli.pp implements a small client application. diff --git a/docs/sockex/foot.tex b/docs/sockex/foot.tex new file mode 100644 index 0000000000..83788a402a --- /dev/null +++ b/docs/sockex/foot.tex @@ -0,0 +1,2 @@ +\end{verbatim} +\end{FPKList} \ No newline at end of file diff --git a/docs/sockex/head.tex b/docs/sockex/head.tex new file mode 100644 index 0000000000..b2ed5b6603 --- /dev/null +++ b/docs/sockex/head.tex @@ -0,0 +1,3 @@ +\begin{FPKList} +\item[Example] +\begin{verbatim} diff --git a/docs/sockex/pp2tex b/docs/sockex/pp2tex new file mode 100644 index 0000000000..3a5cd6a448 --- /dev/null +++ b/docs/sockex/pp2tex @@ -0,0 +1,5 @@ +#!/bin/sh +# Simply paste a header and footer to the program. +cat head.tex > $1.tex +cat $1.pp >> $1.tex +cat foot.tex >> $1.tex diff --git a/docs/sockex/sock_cli.pp b/docs/sockex/sock_cli.pp new file mode 100644 index 0000000000..74778d044d --- /dev/null +++ b/docs/sockex/sock_cli.pp @@ -0,0 +1,40 @@ +Program Client; + +{ + Program to test Sockets unit by Michael van Canneyt and Peter Vreman + Client Version, First Run sock_svr to let it create a socket and then + sock_cli to connect to that socket +} + +uses Sockets,Linux; + +procedure PError(const S : string); +begin + writeln(S,SocketError); + halt(100); +end; + + +Var + Saddr : String[25]; + Buffer : string [255]; + S : Longint; + Sin,Sout : Text; + i : integer; +begin + S:=Socket (AF_UNIX,SOCK_STREAM,0); + if SocketError<>0 then + Perror('Client : Socket : '); + Saddr:='ServerSoc'; + if not Connect (S,SAddr,Sin,Sout) then + PError('Client : Connect : '); + Reset(Sin); + ReWrite(Sout); + Buffer:='This is a textstring sent by the Client.'; + for i:=1 to 10 do + Writeln(Sout,Buffer); + Flush(Sout); + Readln(SIn,Buffer); + WriteLn(Buffer); + Close(sout); +end. diff --git a/docs/sockex/sock_svr.pp b/docs/sockex/sock_svr.pp new file mode 100644 index 0000000000..90a7560332 --- /dev/null +++ b/docs/sockex/sock_svr.pp @@ -0,0 +1,49 @@ +Program server; + +{ + Program to test Sockets unit by Michael van Canneyt and Peter Vreman + Server Version, First Run sock_svr to let it create a socket and then + sock_cli to connect to that socket +} + +uses Linux,Sockets; +const + SPath='ServerSoc'; + +Var + FromName : string; + Buffer : string[255]; + S : Longint; + Sin,Sout : Text; + +procedure perror (const S:string); +begin + writeln (S,SocketError); + halt(100); +end; + + + +begin + S:=Socket (AF_UNIX,SOCK_STREAM,0); + if SocketError<>0 then + Perror ('Server : Socket : '); + UnLink(SPath); + if not Bind(S,SPath) then + PError ('Server : Bind : '); + if not Listen (S,1) then + PError ('Server : Listen : '); + Writeln('Waiting for Connect from Client, run now sock_cli in an other tty'); + if not Accept (S,FromName,Sin,Sout) then + PError ('Server : Accept : '); + Reset(Sin); + ReWrite(Sout); + Writeln(Sout,'Message From Server'); + Flush(SOut); + while not eof(sin) do + begin + Readln(Sin,Buffer); + Writeln('Server : read : ',buffer); + end; + Unlink(SPath); +end. diff --git a/docs/stringex/Makefile b/docs/stringex/Makefile new file mode 100644 index 0000000000..5a974eedb1 --- /dev/null +++ b/docs/stringex/Makefile @@ -0,0 +1,53 @@ +####################################################################### +# +# Makefile to compile all examples and convert them to LaTeX +# +####################################################################### + +# Compiler +PP=ppc386 + +# Unit directory +# UNITDIR=/usr/lib/ppc/0.99.0/linuxunits + + +# Any options you wish to pass. +PPOPTS= + +# Script to convert the programs to LaTeX examples which can be included. +PP2TEX=pp2tex + +# Script to collect all examples in 1 file. +MAKETEX=make1tex + +####################################################################### +# No need to edit after this line. +####################################################################### + +ifdef UNITDIR +PPOPTS:=$(PPOPTS) -Up$(UNITDIR); +endif + +.SUFFIXES: .pp .tex + +.PHONY: all tex clean + +OBJECTS=ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex11 ex12 ex13 ex14 ex15 ex16 ex17 + +TEXOBJECTS=$(addsuffix .tex, $(OBJECTS)) + +all : $(OBJECTS) + +tex : $(TEXOBJECTS) + +onetex : tex + $(MAKETEX) $(TEXOBJECTS) + +clean : + rm -f *.o *.s $(OBJECTS) $(TEXOBJECTS) + +$(OBJECTS): %: %.pp + $(PP) $(PPOPTS) $* + +$(TEXOBJECTS): %.tex: %.pp head.tex foot.tex + $(PP2TEX) $* diff --git a/docs/stringex/README b/docs/stringex/README new file mode 100644 index 0000000000..a82fc36802 --- /dev/null +++ b/docs/stringex/README @@ -0,0 +1,20 @@ +These are the example programs that appear in the FPC documentation. + +Units guide, chapter on Strings unit : + +ex1.pp contains an example of the StrLen function. +ex2.pp contains an example of the StrPCopy function. +ex3.pp contains an example of the StrPas function. +ex4.pp contains an example of the StrCopy function. +ex5.pp contains an example of the StrLCopy function. +ex6.pp contains an example of the StrECopy function. +ex7.pp contains an example of the StrEnd function. +ex8.pp contains an example of the StrLComp function. +ex9.pp contains an example of the StrIComp function. +ex10.pp contains an example of the StrMove function. +ex11.pp contains an example of the StrCat function. +ex12.pp contains an example of the StrLCat function. +ex13.pp contains an example of the StrScan and StrRScan functions. +ex14.pp contains an example of the StrLower and StrUpper functions. +ex15.pp contains an example of the StrPos function. +ex16.pp contains an example of the StrNew function. diff --git a/docs/stringex/ex1.pp b/docs/stringex/ex1.pp new file mode 100644 index 0000000000..3e6636fbe5 --- /dev/null +++ b/docs/stringex/ex1.pp @@ -0,0 +1,12 @@ +Program Example1; + +Uses strings; + +{ Program to demonstrate the StrLen function. } + +Const P : PChar = 'This is a constant pchar string'; + +begin + Writeln ('P : ',p); + Writeln ('length(P) : ',StrLen(P)); +end. diff --git a/docs/stringex/ex10.pp b/docs/stringex/ex10.pp new file mode 100644 index 0000000000..ceeb31e12c --- /dev/null +++ b/docs/stringex/ex10.pp @@ -0,0 +1,16 @@ +Program Example10; + +Uses strings; + +{ Program to demonstrate the StrMove function. } + +Const P1 : PCHAR = 'This is a pchar string.'; + + +Var P2 : Pchar; + +begin + P2:=StrAlloc(StrLen(P1)+1); + StrMove (P2,P1,StrLen(P1)+1); { P2:=P1 } + Writeln ('P2 = ',P2); +end. diff --git a/docs/stringex/ex11.pp b/docs/stringex/ex11.pp new file mode 100644 index 0000000000..bcc47ccf3a --- /dev/null +++ b/docs/stringex/ex11.pp @@ -0,0 +1,16 @@ +Program Example11; + +Uses strings; + +{ Program to demonstrate the StrCat function. } + +Const P1 : PChar = 'This is a PChar String.'; + +Var P2 : PChar; + +begin + P2:=StrAlloc (StrLen(P1)*2+1); + StrMove (P2,P1,StrLen(P1)+1); { P2=P1 } + StrCat (P2,P1); { Append P2 once more } + Writeln ('P2 : ',P2); +end. diff --git a/docs/stringex/ex12.pp b/docs/stringex/ex12.pp new file mode 100644 index 0000000000..1906919250 --- /dev/null +++ b/docs/stringex/ex12.pp @@ -0,0 +1,17 @@ +Program Example12; + +Uses strings; + +{ Program to demonstrate the StrLCat function. } + +Const P1 : PChar = '1234567890'; + +Var P2 : PChar; + +begin + P2:=StrAlloc (StrLen(P1)*2+1); + P2^:=#0; { Zero length } + StrCat (P2,P1); + StrLCat (P2,P1,5); + Writeln ('P2 = ',P2); +end. diff --git a/docs/stringex/ex13.pp b/docs/stringex/ex13.pp new file mode 100644 index 0000000000..b21419da5b --- /dev/null +++ b/docs/stringex/ex13.pp @@ -0,0 +1,13 @@ +Program Example13; + +Uses strings; + +{ Program to demonstrate the StrScan and StrRScan functions. } + +Const P : PChar = 'This is a PCHAR string.'; + S : Char = 's' ; + +begin + Writeln ('P, starting from first ''s'' : ',StrScan(P,s)); + Writeln ('P, starting from last ''s'' : ',StrRScan(P,s)); +end. diff --git a/docs/stringex/ex14.pp b/docs/stringex/ex14.pp new file mode 100644 index 0000000000..eb8555bd49 --- /dev/null +++ b/docs/stringex/ex14.pp @@ -0,0 +1,15 @@ +Program Example14; + +Uses strings; + +{ Program to demonstrate the StrLower and StrUpper functions. } + +Const + P1 : PChar = 'THIS IS AN UPPERCASE PCHAR STRING'; + P2 : PChar = 'this is a lowercase string'; + +begin + Writeln ('Uppercase : ',StrUpper(P2)); + StrLower (P1); + Writeln ('Lowercase : ',P1); +end. diff --git a/docs/stringex/ex15.pp b/docs/stringex/ex15.pp new file mode 100644 index 0000000000..a0f7cdaf05 --- /dev/null +++ b/docs/stringex/ex15.pp @@ -0,0 +1,11 @@ +Program Example15; + +Uses strings; + +{ Program to demonstrate the StrPos function. } + +Const P : PChar = 'This is a PChar string.'; + S : Pchar = 'is'; +begin + Writeln ('Position of ''is'' in P : ',longint(StrPos(P,S))-Longint(P)); +end. diff --git a/docs/stringex/ex16.pp b/docs/stringex/ex16.pp new file mode 100644 index 0000000000..964387b282 --- /dev/null +++ b/docs/stringex/ex16.pp @@ -0,0 +1,17 @@ +Program Example16; + +Uses strings; + +{ Program to demonstrate the StrNew function. } + +Const P1 : PChar = 'This is a PChar string'; + +var P2 : PChar; + +begin + P2:=StrNew (P1); + If P1=P2 then + writeln ('This can''t be happening...') + else + writeln ('P2 : ',P2); +end. diff --git a/docs/stringex/ex17.pp b/docs/stringex/ex17.pp new file mode 100644 index 0000000000..cbbea0c70a --- /dev/null +++ b/docs/stringex/ex17.pp @@ -0,0 +1,18 @@ +Program Example17; + +Uses strings; + +{ Program to demonstrate the StrDispose function. } + +Const P1 : PChar = 'This is a PChar string'; + +var P2 : PChar; + +begin + Writeln ('Before StnNew : Memory available : ',MemAvail); + P2:=StrNew (P1); + Writeln ('After StrNew : Memory available : ',MemAvail); + Writeln ('P2 : ',P2); + StrDispose(P2); + Writeln ('After StrDispose : Memory available : ',MemAvail); +end. diff --git a/docs/stringex/ex2.pp b/docs/stringex/ex2.pp new file mode 100644 index 0000000000..99937821ee --- /dev/null +++ b/docs/stringex/ex2.pp @@ -0,0 +1,17 @@ +Program Example2; + +Uses strings; + +{ Program to demonstrate the StrPCopy function. } + +Const S = 'This is a normal string.'; + +Var P : Pchar; + +begin + p:=StrAlloc (length(S)+1); + if StrPCopy (P,S)<>P then + Writeln ('This is impossible !!') + else + writeln (P); +end. diff --git a/docs/stringex/ex3.pp b/docs/stringex/ex3.pp new file mode 100644 index 0000000000..fafdf7d5d5 --- /dev/null +++ b/docs/stringex/ex3.pp @@ -0,0 +1,14 @@ +Program Example3; + +Uses strings; + +{ Program to demonstrate the StrPas function. } + +Const P : PChar = 'This is a PCHAR string'; + +var S : string; + +begin + S:=StrPas (P); + Writeln ('S : ',S); +end. diff --git a/docs/stringex/ex4.pp b/docs/stringex/ex4.pp new file mode 100644 index 0000000000..182ccc0c2b --- /dev/null +++ b/docs/stringex/ex4.pp @@ -0,0 +1,18 @@ +Program Example4; + +Uses strings; + +{ Program to demonstrate the StrCopy function. } + +Const P : PCHar = 'This is a PCHAR string.'; + +var PP : PChar; + +begin + PP:=StrAlloc(Strlen(P)+1); + STrCopy (PP,P); + If StrComp (PP,P)<>0 then + Writeln ('Oh-oh problems...') + else + Writeln ('All is well : PP=',PP); +end. diff --git a/docs/stringex/ex5.pp b/docs/stringex/ex5.pp new file mode 100644 index 0000000000..5d8866564a --- /dev/null +++ b/docs/stringex/ex5.pp @@ -0,0 +1,14 @@ +Program Example5; + +Uses strings; + +{ Program to demonstrate the StrLCopy function. } + +Const P : PCHar = '123456789ABCDEF'; + +var PP : PCHar; + +begin + PP:=StrAlloc(11); + Writeln ('First 10 characters of P : ',StrLCopy (PP,P,10)); +end. diff --git a/docs/stringex/ex6.pp b/docs/stringex/ex6.pp new file mode 100644 index 0000000000..0fb07e39ef --- /dev/null +++ b/docs/stringex/ex6.pp @@ -0,0 +1,17 @@ +Program Example6; + +Uses strings; + +{ Program to demonstrate the StrECopy function. } + +Const P : PChar = 'This is a PCHAR string.'; + +Var PP : PChar; + +begin + PP:=StrAlloc (StrLen(P)+1); + If Longint(StrECopy(PP,P))-Longint(PP)<>StrLen(P) then + Writeln('Something is wrong here !') + else + Writeln ('PP= ',PP); +end. diff --git a/docs/stringex/ex7.pp b/docs/stringex/ex7.pp new file mode 100644 index 0000000000..3ef75ded0c --- /dev/null +++ b/docs/stringex/ex7.pp @@ -0,0 +1,14 @@ +Program Example6; + +Uses strings; + +{ Program to demonstrate the StrEnd function. } + +Const P : PChar = 'This is a PCHAR string.'; + +begin + If Longint(StrEnd(P))-Longint(P)<>StrLen(P) then + Writeln('Something is wrong here !') + else + Writeln ('All is well..'); +end. diff --git a/docs/stringex/ex8.pp b/docs/stringex/ex8.pp new file mode 100644 index 0000000000..6688be4c5a --- /dev/null +++ b/docs/stringex/ex8.pp @@ -0,0 +1,20 @@ +Program Example8; + +Uses strings; + +{ Program to demonstrate the StrLComp function. } + +Const P1 : PChar = 'This is the first string.'; + P2 : PCHar = 'This is the second string.'; + +Var L : Longint; + +begin + Write ('P1 and P2 are '); + If StrComp (P1,P2)<>0 then write ('NOT '); + write ('equal. The first '); + L:=1; + While StrLComp(P1,P2,L)=0 do inc (L); + dec(l); + Writeln (l,' characters are the same.'); +end. diff --git a/docs/stringex/ex9.pp b/docs/stringex/ex9.pp new file mode 100644 index 0000000000..103cc8c998 --- /dev/null +++ b/docs/stringex/ex9.pp @@ -0,0 +1,20 @@ +Program Example9; + +Uses strings; + +{ Program to demonstrate the StrIComp function. } + +Const P1 : PCHAR = 'This is a pchar string.'; + P2 : PCHAR = 'This is a PCHAR string.'; + P3 : PCHAR = 'tHiS iS aLsO a PCHAR string'; + +Var L : Longint; + +begin + If StrIComp (P1,P2)<>0 then writeln ('Something wrong here !'); + Write ('P2 and P3 match in their first '); + L:=1; + While StrLIComp (P2,P3,L)=0 do inc(L); + Dec(L); + Writeln (L,'characters, case insensitive.'); +end. diff --git a/docs/stringex/foot.tex b/docs/stringex/foot.tex new file mode 100644 index 0000000000..83788a402a --- /dev/null +++ b/docs/stringex/foot.tex @@ -0,0 +1,2 @@ +\end{verbatim} +\end{FPKList} \ No newline at end of file diff --git a/docs/stringex/head.tex b/docs/stringex/head.tex new file mode 100644 index 0000000000..b2ed5b6603 --- /dev/null +++ b/docs/stringex/head.tex @@ -0,0 +1,3 @@ +\begin{FPKList} +\item[Example] +\begin{verbatim} diff --git a/docs/stringex/newex b/docs/stringex/newex new file mode 100644 index 0000000000..45f07f89e7 --- /dev/null +++ b/docs/stringex/newex @@ -0,0 +1,8 @@ +#!/bin/sh +if [ -e ex${1}.pp ]; then + mv ex${1}.pp ex${1}.pp.orig +fi +sed -e s/Example/Example$1/ -e s/\\\*\\\*\\\*/$2/ ex${1}.pp +echo "ex${1}.pp contains an example of the $2 function." >>README +joe ex${1}.pp +ppc386 ex${1}.pp && ex${1} diff --git a/docs/stringex/pp2tex b/docs/stringex/pp2tex new file mode 100644 index 0000000000..3a5cd6a448 --- /dev/null +++ b/docs/stringex/pp2tex @@ -0,0 +1,5 @@ +#!/bin/sh +# Simply paste a header and footer to the program. +cat head.tex > $1.tex +cat $1.pp >> $1.tex +cat foot.tex >> $1.tex diff --git a/docs/stringex/template.pp b/docs/stringex/template.pp new file mode 100644 index 0000000000..69a2ab2b2a --- /dev/null +++ b/docs/stringex/template.pp @@ -0,0 +1,8 @@ +Program Example; + +Uses strings; + +{ Program to demonstrate the *** function. } + +begin +end. diff --git a/docs/strings.tex b/docs/strings.tex new file mode 100644 index 0000000000..4cbc0f2665 --- /dev/null +++ b/docs/strings.tex @@ -0,0 +1,256 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\chapter{The STRINGS unit.} +This chapter describes the \var{STRINGS} unit for +\fpk. + +Since the unit only provides some procedures and functions, there is +only one section, which gives the declarations of these functions, together +with an explanation. + +\section{Functions and procedures.} + +\function{StrLen}{(p : PChar)}{Longint} +{ +Returns the length of the null-terminated string \var{P}. +} +{None.}{\seem{Length}{}} + +\input{stringex/ex1.tex} + +\function{StrPCopy}{(Dest : PChar; Const Source : String)}{PChar} +{ +Converts the Pascal string in \var{Source} to a Null-terminated +string, and copies it to \var{Dest}. \var{Dest} needs enough room to contain +the string \var{Source}, i.e. \var{Length(Source)+1} bytes. +} +{No length checking is performed.}{ \seef{StrPas}} + +\input{stringex/ex2.tex} + +\function {StrPas}{(P : PChar)}{String} +{ +Converts a null terminated string in \var{P} to a Pascal string, and returns +this string. The string is truncated at 255 characters. +} +{None.}{ \seef{StrPCopy}} + +\input{stringex/ex3.tex} + +\function {StrCopy}{(Dest,Source : PChar)}{PChar} +{ +Copy the null terminated string in \var{Source} to \var{Dest}, and +returns a pointer to \var{Dest}. \var{Dest} needs enough room to contain +\var{Source}, i.e. \var{StrLen(Source)+1} bytes. +} +{No length checking is performed.}{ \seef{StrPCopy}, \seef{StrLCopy}, \seef{StrECopy}} + +\input{stringex/ex4.tex} + +\function{StrLCopy}{(Dest,Source : PChar; MaxLen : Longint)}{PChar} +{ +Copies \var{MaxLen} characters from \var{Source} to \var{Dest}, and makes +\var{Dest} a null terminated string. +} +{No length checking is performed.} +{\seef{StrCopy}, \seef{StrECopy}} + +\input{stringex/ex5.tex} + +\function{StrECopy}{(Dest,Source : PChar)}{PChar} +{ +Copies the Null-terminated string in \var{Source} to \var{Dest}, and +returns a pointer to the end (i.e. the terminating Null-character) of the +copied string. +} +{No length checking is performed.} +{\seef{StrLCopy}, \seef{StrCopy}} + +\input{stringex/ex6.tex} + +\function{StrEnd}{(P : PChar)}{PChar} +{ +Returns a pointer to the end of \var{P}. (i.e. to the terminating +null-character. +} +{None.}{\seef{StrLen}} + +\input{stringex/ex7.tex} + +\function{StrCat}{(Dest,Source : PChar)}{PChar} +{ +Attaches \var{Source} to \var{Dest} and returns \var{Dest}. +} +{No length checking is performed.} +{\seem{Concat}{}} + +\input{stringex/ex11.tex} + +\function{StrComp}{(S1,S2 : PChar)}{Longint} +{ +Compares the null-terminated strings \var{S1} and \var{S2}. + +The result is +\begin{itemize} +\item A negative \var{Longint} when \var{S1S2}. +\end{itemize} +} +{None.}{\seef{StrLComp}, \seef{StrIComp}, \seef{StrLIComp}} + +For an example, see \seef{StrLComp}. + +\function{StrLComp}{(S1,S2 : PChar; L : Longint)}{Longint} +{ +Compares maximum \var{L} characters of the null-terminated strings +\var{S1} and \var{S2}. + +The result is +\begin{itemize} +\item A negative \var{Longint} when \var{S1S2}. +\end{itemize} +} +{None.}{\seef{StrComp}, \seef{StrIComp}, \seef{StrLIComp}} + +\input{stringex/ex8.tex} + +\function{StrIComp}{(S1,S2 : PChar)}{Longint} +{ +Compares the null-terminated strings \var{S1} and \var{S2}, ignoring case. + +The result is +\begin{itemize} +\item A negative \var{Longint} when \var{S1S2}. +\end{itemize} +} +{None.}{\seef{StrLComp}, \seef{StrComp}, \seef{StrLIComp}} + +\input{stringex/ex8.tex} + +\function{StrLIComp}{(S1,S2 : PChar; L : Longint)}{Longint} +{ +Compares maximum \var{L} characters of the null-terminated strings \var{S1} +and \var{S2}, ignoring case. + +The result is +\begin{itemize} +\item A negative \var{Longint} when \var{S1S2}. +\end{itemize} +} +{None.}{\seef{StrLComp}, \seef{StrComp}, \seef{StrIComp}} + +For an example, see \seef{StrIComp} + +\function{StrMove}{(Dest,Source : PChar; MaxLen : Longint)}{PChar} +{ +Copies \var{MaxLen} characters from \var{Source} to \var{Dest}. No +terminating null-character is copied. +Returns \var {Dest}. +} +{None.}{\seef{StrLCopy}, \seef{StrCopy}} + +\input{stringex/ex10.tex} + +\function{StrLCat}{(Dest,Source : PChar; MaxLen : Longint)}{PChar} +{ +Adds \var{MaxLen} characters from \var{Source} to \var{Dest}, and adds a +terminating null-character. Returns \var{Dest}. +} +{None.}{\seef{StrCat}} + +\input{stringex/ex12.tex} + +\function{StrScan}{(P : PChar; C : Char)}{PChar} +{ +Returns a pointer to the first occurrence of the character \var{C} in the +null-terminated string \var{P}. If \var{C} does not occur, returns +\var{Nil}. +} +{None.}{\seem{Pos}{}, \seef{StrRScan}, \seef{StrPos}} + +\input{stringex/ex13.tex} + +\function{StrRScan}{(P : PChar; C : Char)}{PChar} +{ +Returns a pointer to the last occurrence of the character \var{C} in the +null-terminated string \var{P}. If \var{C} does not occur, returns +\var{Nil}. +} +{None.}{\seem{Pos}{}, \seef{StrScan}, \seef{StrPos}} + +For an example, see \seef{StrScan}. + +\function{StrLower}{(P : PChar)}{PChar} +{ +Converts \var{P} to an all-lowercase string. Returns \var{P}. +} +{None.}{\seem{Upcase}{}, \seef{StrUpper}} + +\input{stringex/ex14.tex} + +\function{StrUpper}{(P : PChar)}{PChar} +{ +Converts \var{P} to an all-uppercase string. Returns \var{P}. +} +{None.}{\seem{Upcase}{}, \seef{StrLower}} + +For an example, see \seef{StrLower} + +\function{StrPos}{(S1,S2 : PChar)}{PChar} +{ +Returns a pointer to the first occurrence of \var{S2} in \var{S1}. +If \var{S2} does not occur in \var{S1}, returns \var{Nil}. +} +{None.}{\seem{Pos}{}, \seef{StrScan}, \seef{StrRScan}} + +\input{stringex/ex15.tex} + +\function{StrNew}{(P : PChar)}{PChar} +{ +Copies \var{P} to the Heap, and returns a pointer to the copy. +} +{Returns \var{Nil} if no memory was available for the copy.} +{\seem{New}{}, \seef{StrCopy}, \seep{StrDispose}} + +\input{stringex/ex16.tex} + +\procedure{StrDispose}{(P : PChar)} +{ +Removes the string in \var{P} from the heap and releases the memory. +} +{None.}{\seem{Dispose}{}, \seef{StrNew}} + +\input{stringex/ex17.tex} + +\procedure{StrAlloc}{(Len : Longint)}{PChar} +{ +\var{StrAlloc} reserves memory on the heap for a string with length \var{Len}, +terminating \var{\#0} included, and returns a pointer to it. +} + +For an example, see \seef{StrPCopy}. diff --git a/docs/units.tex b/docs/units.tex new file mode 100644 index 0000000000..873235377e --- /dev/null +++ b/docs/units.tex @@ -0,0 +1,101 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\documentclass{report} +% +% This is just a main file. All units are described in separate files. +% +% Preamble +% +\usepackage{a4} +\usepackage{makeidx} +\usepackage{html} +\latex{\usepackage{fpk}} +\html{\input{fpk-html.tex}} +\makeindex + +% +% start of document. +% +\begin{document} +\title{Free Pascal supplied units : \\ Reference guide.} +\docdescription{Reference guide for standard Free Pascal units.} +\docversion{1.2} +\date{July 1997} +\author{Micha\"el Van Canneyt\\ Florian Kl\"ampfl} +\maketitle +\tableofcontents +\newpage + +\section*{About this guide} +This document describes all constants, types, variables, functions and +procedures as they are declared in the units that come standard with \fpk. + +Throughout this document, we will refer to functions, types and variables +with \var{typewriter} font. Functions and procedures gave their own +subsections, and for each function or procedure we have the following +topics: +\begin{description} +\item [Declaration] The exact declaration of the function. +\item [Description] What does the procedure exactly do ? +\item [Errors] What errors can occur. +\item [See Also] Cross references to other related functions/commands. +\end{description} +The cross-references come in two flavors: +\begin{itemize} +\item References to other functions in this manual. In the printed copy, a +number will appear after this reference. It refers to the page where this +function is explained. In the on-line help pages, this is a hyperlink, on +which you can click to jump to the declaration. +\item References to Unix manual pages. (For Linux related things only) they +are printed in \var{typewriter} font, and the number after it is the Unix +manual section. +\end{itemize} +The chapters are ordered alphabetically. The functions and procedures in +most cases also, but don't count on it. Use the table of contents for quick +lookup. + +% +% Each unit is in its own file. Each file is a chapter. +% + +% The crt unit. +\input{crt.tex} +% The Dos unit +\input{dos.tex} +% The getopts unit +\input{getopts.tex} +% the go32 unit +\input{go32.tex} +% The graph unit +\input{graph.tex} +% the Linux unit +\input{linux.tex} +% The MMX unit +\input{mmx.tex} +% the printer unit +\input{printer.tex} +% the sockets unit +\input{sockets.tex} +% the strings unit +\input{strings.tex} + +\printindex +\end{document} diff --git a/docs/unitspdf.tex b/docs/unitspdf.tex new file mode 100644 index 0000000000..3e6cc9a1a8 --- /dev/null +++ b/docs/unitspdf.tex @@ -0,0 +1,22 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\pdfoutput=1 +\input{units.tex} \ No newline at end of file diff --git a/docs/user.tex b/docs/user.tex new file mode 100644 index 0000000000..1f445fbe9e --- /dev/null +++ b/docs/user.tex @@ -0,0 +1,2343 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\documentclass{report} +\usepackage{a4} +\usepackage{html} +\makeindex +\latex{\usepackage{multicol}} +\latex{\usepackage{fpkman}} +\html{\input{fpk-html.tex}} +% define the version number here, and not in the fpk.sty !!! +\newcommand{\fpkversion}{0.9.5} +\newcommand{\remark}[1]{\par$\rightarrow$\textbf{#1}\par} +% define many-used references. +%\newcommand{\progref}{\htmladdnormallink{Programmer's guide}{../prog/prog.html}\ } +%\newcommand{\refref}{\htmladdnormallink{Reference guide}{../ref/ref.html}\ } +%\newcommand{\seecrt}{\htmladdnormallink{CRT}{../crt/crt.html}} +%\newcommand{\seelinux}{\htmladdnormallink{Linux}{../linux/linux.html}} +%\newcommand{\seestrings}{\htmladdnormallink{strings}{../strings/strings.html}} +%\newcommand{\seedos}{\htmladdnormallink{DOS}{../dos/dos.html}} +%\newcommand{\seegetopts}{\htmladdnormallink{getopts}{../getopts/getopts.html}} +%\newcommand{\seeobjects}{\htmladdnormallink{objects}{../objects/objects.html}} +%\newcommand{\seegraph}{\htmladdnormallink{graph}{../graph/graph.html}} +%\newcommand{\seeprinter}{\htmladdnormallink{printer}{../printer/printer.html}} +%\newcommand{\seego}{\htmladdnormallink{GO32}{../go32/go32.html}} +% +\newcommand{\olabel}[1]{\label{option:#1}} +% We should change this to something better. See \seef etc. +\newcommand{\seeo}[1]{See \ref{option:#1}} +\begin{document} +\title{Free Pascal :\\ User's manual} +\docdescription{User's manual for \fpk, version \fpkversion} +\docversion{1.0} +\date{July 1997} +\author{Micha\"el Van Canneyt\\Florian Kl\"ampfl} +\maketitle +\tableofcontents +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Introduction +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Introduction} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% About this document +\section{About this document} +This is the user's manual for \fpk . It describes the installation and use of +the \fpk compiler on the different supported platforms. +It does not attempt to give an exhaustive list of all supported commands, +nor a definition of the Pascal language. Look at the +\refref for these things. +For a description of the +possibilities and the inner workings of the compiler, see the +\progref. In the appendices of this document you will find lists of +reserved words and compiler error messages (with descriptions). + +This document describes the compiler as it is/functions at the time of +writing. Since the compiler is under continuous development, some of the +things described here may be outdated. In case of doubt, consult the +\file{README} files, distributed with the compiler. +The \file{README} files are, in case of conflict with this manual, + authoritative. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% About the compiler +\section{About the compiler} +\fpk is a 32-bit compiler for the i386 processor\footnote{Work is being done +on a port to ALPHA Architecture}. Currently, it supports 2 operating systems: +\begin{itemize} +\item \dos +\item \linux +\end{itemize} +and work is in progress to port it to other platforms (notably, \ostwo and +\windowsnt). + +\fpk is designed to be, as much as possible, source compatible with +Turbo Pascal 7.0 and Delphi II (although this goal is not yet attained), +but it also enhances these languages with elements like function overloading. +And, unlike these ancestors, it supports multiple platforms. + +It also differs from them in the sense that you cannot use compiled units +from one system for the other. + +Also, at the time of writing, there is no Integrated Development Environment +(IDE) available for \fpk. This gap will, hopefully, be filled in the future. + +\fpk consists of three parts : +\begin{enumerate} +\item The compiler program itself. +\item The Run-Time Library (RTL). +\item Utility programs and units. +\end{enumerate} + +Of these you only need the first two, in order to be able to use the compiler. +In this document, we describe the use of the compiler. The RTL is described in the +\refref. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Getting more information. +\section{Getting more information.} +If the documentation doesn't give an answer to your questions, +you can obtain more information on the Internet, on the following addresses: +\begin{itemize} +\item \htmladdnormallink{http://tfdec1.fys.kuleuven.ac.be/\~ michael/fpk.html} +{http://tfdec1.fys.kuleuven.ac.be/~michael/fpk.html} contains information +on the \linux port of the compiler. It contains also useful mail addresses and +links to other places. +\item \htmladdnormallink{http://www.brain.uni-freiburg.de/\~klaus/fpk-pas} +{http://www.brain.uni-freiburg.de/~klaus/fpk-pas} is the main \fpk information site. +It also contains the instructions for inscribing to the \textit{mailing-list}, +another useful source of information. +\end{itemize} +Both places can be used to download the \fpk distribution, although you can +probably find them on other places also. + +Finally, if you think something should be added to this manual +(entirely possible), please do not hesitate and contact me at +\htmladdnormallink{michael@tfdec1.fys.kuleuven.ac.be}{mailto:michael@tfdec1.fys.kuleuven.ac.be} +. + +Let's get on with something useful. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Installation +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Installing the compiler} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Before Installation : Requirements +\section{Before Installation : Requirements} + +% +% + +% System requirements +\subsection{System requirements} +The compiler needs at least the following hardware: +\begin{enumerate} +\item An I386 or higher processor. A coprocessor is not required, although it +will slow down your program's performance if you do floating point calculations. +\item 4 Mb of free memory. Under \dos, if you use DPMI memory management, +such as under Windows, you will need at least 8 Mb. +\item At least 500 Kb. free disk space. +\end{enumerate} + +% +% + +% Software requirements +\subsection{Software requirements} + +\subsubsection{Under DOS} +The \dos distribution contains all the files you need to run the compiler +and compile pascal programs. + +\subsubsection{Under Linux} +Under \linux you need to have the following programs installed : +\begin{enumerate} +\item \gnu \file{as}, the \gnu assembler. +\item \gnu \file{ld}, the \gnu linker. +\item Optionally (but highly recommended) : \gnu \file{make}. For easy +recompiling of the compiler and Run-Time Library, this is needed. +\end{enumerate} +Other than that, \fpk should run on almost any \linux system. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Installing the compiler. +\section{Installing the compiler.} +The installation of \fpk is easy, but is platform-dependent. +We discuss the process for each platform separately. + + +% +% + +% Installing under DOS +\subsection{Installing under DOS} +\subsubsection{Mandatory installation steps.} +First, you must get the latest distribution files of \fpk. They come as zip +files, which you must unzip first. The distribution zip file contains an +installation program \file{INSTALL.EXE}. You must run this program to install +the compiler. It allows you to select: +\begin{itemize} +\item What components you wish to install. (e.g do you want the sources or +not, do you want Free Vision etc.) +\item Where you want to install (the default location is \verb|C:\PP|). +\end{itemize} +The installation program generates a batch file which sets some environment +variables : \verb|SET_PP.BAT|. This file is located in the directory where +you installed \fpk. The installation program doesn't modify the +\file{AUTOEXEC.BAT}, since many people (including the authors of \fpk) +don't like this. + +You can choose to insert a call to this batch file in your \file{AUTOEXEC.BAT} +file, like this : +\begin{verbatim} + CALL C:\PP\SET_PP.BAT +\end{verbatim} +(This is assuming that you installed \fpk in the default location.) +In order to run \fpk from any directory on your system, you must extend +your path variable to contain the \verb|C:\PP\BIN| directory. +You can choose to do this in your \file{AUTOEXEC.BAT} file, but you can also +insert a statement in the \verb|SET_PP.BAT| file. Whatever the location you +choose, It should look something like this : +\begin{verbatim} + SET PATH=%PATH%;C:\PP\BIN +\end{verbatim} +(Again, assuming that you installed in the default location). + +If you want to use the graphic drivers you must modify the +environment variable \var{GO32}. Instructions for doing this can be found +in the documentation of the Graph unit, at the InitGraph procedure. + +\subsubsection{Optional Installation: The coprocessor emulation} +For people who have an older CPU type, without math coprocessor (i387) +it is necessary to install a coprocessor emulation, since \fpk uses the +coprocessor to do all floating point operations. + +The installation of the coprocessor emulation is handled by the +installation program (\file{INSTALL.EXE}). However, +the installation program has currently a bug: If you select the +coprocessor emulation the program ignores this and you must do +this by hand. You should change the \var{GO32} environment variable in +the \verb|SET_PP.BAT| file, as follows: +\begin{verbatim} +SET GO32=emu C:\PP\DRIVERS\EMU387 +\end{verbatim} + + +% +% + +% Installing under Linux +\subsection{Installing under Linux} +\subsubsection{Mandatory installation steps.} +The \linux distribution of \fpk comes in two flavors: +\begin{itemize} +\item an \file{aout} version, and +\item an \file{ELF} version. +\end{itemize} +If you don't know which of these flavors you must use, contact you system +administrator, and he will tell you. When that doesn't get you further, try +the \file{ELF} distribution. \file{aout} systems are outdated, and may not be +supported any more in the future. + +Both flavors are shipped in \file{tar} archive files. +This means that you should untar them, in some directory where you have +write permission, using the following command: +\begin{verbatim} +tar -xvf fpk.tar +\end{verbatim} +We supposed here that you downloaded the file \file{fpk.tar} somewhere +from the Internet. + +When the files are untarred, you will be left with more archive files, and +two install programs: an installation shell script, and a X-windows +installation program. Both have the same functionality. +To install \fpk, all that you need to do now is give the following command: +\begin{verbatim} +./install.sh +\end{verbatim} +Or, if you have the XForms libraries, you can start the X-Windows based +program. +\begin{verbatim} +./fpkinstall +\end{verbatim} +And then you must answer some questions. They're very simple, they're +concerned with 2 things : +\begin{enumerate} +\item Places where you can install different things. +\item Deciding if you want to install certain components (such as sources +and demo programs). +\end{enumerate} +If you run the installation program/script as \var{root}, you can just accept all installation +defaults. If you don't run as \var{root}, you must take care to supply the +installation program with directory names where you have write permission, +as it will attempt to create the directories you specify. +In principle, you can install it wherever you want, though. + +Whatever the installation program you used, +at the end of installation, the installation program will generate a +configuration file for the \fpk compiler which reflects the settings +that you chose. It will install this file in the \file{/etc} directory, (if +you are not installing as \var{root}, this will fail, and in the +directory where you installed the libraries. + +If you want the \fpk compiler to use this configuration file, it must be +present in \file{/etc}, or you can set the environment variable +\var{PPC\_CONFIG\_PATH}. Under \file{csh}, you can do this by adding a +\begin{verbatim} +setenv PPC_CONFIG_PATH /usr/lib/ppc/0.9.1 +\end{verbatim} +line to your \file{.login} file in your home directory. +(see also the next section) + +\subsubsection{Optional configuration steps} +You may wish to set some environment variables. The \linux version of \fpk +recognizes the following variables : +\begin{itemize} +\item \verb|PPC_EXEC_PATH| contains the directory where '\file{as}' and +'\file{ld}' are. (default \file{/usr/bin}) +\item \verb|PPC_GCCLIB_PATH| contains the directory where \file{libgcc.a} is (no default) +\item \verb|PPC_CONFIG_PATH| specifies an alternate path to find +\file{ppc386.cfg} (default \file{/etc}) +\item \verb|PPC_ERROR_FILE| specifies the path and name of the error-definition file. + (default \file{/usr/lib/ppc/errorE.msg}) +\end{itemize} + +These locations are, however, set in the sample configuration file which is +built at the end of the installation process, except for the +\verb|PPC_CONFIG_PATH| variable, which you must set if you didn't install +things in the default places. +\subsubsection{finally} +Also distributed in \fpk is a README file. It contains the latest +instructions for installing \fpk, and should always be read first. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Testing the compiler +\section{Testing the compiler} +After the installation is completed and the environment variables are +set as described above, your first program can be compiled. + +Included in the \fpk distribution are some demonstration programs, +showing what the compiler can do. +You can test if the compiler functions correctly by trying to compile +these programs. + +The compiler is called +\begin{itemize} +\item \file{PPC386.EXE} under \dos, and +\item \file{ppc386} under \linux +\end{itemize} +To compile a program (e.g \verb|demo\hello.pp|) simply type : +\begin{verbatim} + ppc386 -a hello +\end{verbatim} +at the command prompt. The option -a is needed currently to call +the external assembler. +This needed option will disappear when the the internal assembler works stable. +but at the moment it is a mandatory option. + +If you got no error messages, the compiler has generated an executable +called \file{hello} (no extension) under \linux, and a file \file{hello.exe} +under \dos. + +To execute the program, simply type : +\begin{verbatim} + hello +\end{verbatim} +If all went well, you should see the following friendly greeting: +\begin{verbatim} +Hello world +\end{verbatim} +In the \dos case, this friendly greeting may be preceded by some ugly +message from the \file{GO32} extender program. This unfriendly behavior can +be switched off by setting the \file{GO32} environment variable. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Usage +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Compiler usage} +Here we describe the essentials to compile a program and a unit. +We also describe how to make a stand-alone executable of the +compiled program under \dos. For more advanced uses of the compiler, +see the section on configuring the compiler, and the +\progref. + +The examples in this section suppose that you have a \file{ppc386.cfg} which +is set up correctly, and which contains at least the path setting for the +RTL units. In principle this file is generated by the installation program. +You may have to check that it is in the correct place (see section +\ref{se:config_file} for more information on this). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Compiling a program +\section{Compiling a program} +Compiling a program is very simple. Assuming that you have a program source +in the file \file{prog.pp}, you can compile this with the following command: +\begin{verbatim} + ppc386 [options] prog.pp +\end{verbatim} +The square brackets [] indicate that what is between them is optional. + +If your program file has the \file{.pp} or \file{.pas} extension, +you can omit this on the command line, e.g. in the previous example you +could have typed: +\begin{verbatim} + ppc386 [options] prog +\end{verbatim} + +If all went well, the compiler will produce an executable, or, for version 1 +of the \dos extender, a file which can be converted to an executable. + +Under \linux and version 2 of the \dos extender, the file you obtained is +the executable. You can execute it straight away, you don't need to do +anything else. Under \dos, +additional processing is required. See the section on creating an +executable. + +You will notice that there are also other files in your directory, with +extensions \file{.o} and \file{.s}. These contain, respectively, +the assembler sources and the object files for your program. You can +safely delete the assembler file, you don't need it any +more\footnote{One day this will be done automatically.}. If you compiled a +program, you can delete the object file (\file{.o}), but not if you compiled +a unit. Then the object file contains the code of the unit, and will be +linked in any program that uses the unit you compiled, so you shpuldn't +remove it. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Compiling a unit +\section{Compiling a unit} + +Compiling a unit is not essentially different from compiling a program. +The difference is mainly that the linker isn't called in this case. + +To compile a unit in the file \file{foo.pp}, just type : +\begin{verbatim} + ppc386 foo +\end{verbatim} +Recall the remark about file extensions in the previous section. + +When all went well, you will be left with 2 (two) unit files: +\begin{enumerate} +\item \file{foo.ppu} This is the file describing the unit you just +compiled. +\item \file{foo.o} This file contains the actual code of the unit. +This file will eventually end up in the executables. +\end{enumerate} +Both files are needed if you plan to use the unit for some programs. +So don't delete them. If you want to distribute the unit, you must +provide both the \file{.ppu} and \file{.o} file. One is useless without the +other. + +The file containing the assembler (extension \file{.s}) can safely be +deleted. You don't need it anymore. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Creating an executable for GO32V1, PMODE/DJ targets +\section{Creating an executable for GO32V1, PMODE/DJ targets} + +This section applies only to \dos users. \linux users can skip this +section (unless they're cross-compiling) + + +% +% + +% GO32V1 +\subsection{GO32V1} +When compiling under \dos, GO32V2 is the default target. However, if you use +go32V1 (using the \var{-TDOS} switch), the +compilation process leaves you with a file which you cannot execute right away. +There are 2 things you can do when compiling has finished. + +The first thing is to use the \dos extender from D.J. Delorie to execute +your program : +\begin{verbatim} + go32 prog +\end{verbatim} +This is fine for testing, but if you want to use a program regularly, it +would be easier if you could just type the program name, i.e. +\begin{verbatim} + prog +\end{verbatim} +This can be accomplished by making a \dos executable of your compiled program. + +There two ways to create a \dos executable (under \dos only): +\begin{enumerate} +\item if the \file{GO32.EXE} is already +installed on the computers where the program should run, you must +only copy a program called \file{STUB.EXE} at the begin of +the AOUT file. This is accomplished with the \file{AOUT2EXE.EXE} program. +which comes with the compiler: +\begin{verbatim} +AOUT2EXE PROG +\end{verbatim} +and you get a \dos executable which loads the \file{GO32.EXE} automatically. +the \file{GO32.EXE} executable must be in current directory or be +in a directory in the \var{PATH} variable. +\item +The second way to create a \dos executable is to put +\file{GO32.EXE} at the beginning of the \file{AOUT} file. To do this, at the +command prompt, type : +\begin{verbatim} +COPY /B GO32.EXE+PROG PROG.EXE +\end{verbatim} +(assuming \fpk created a file called \file{PROG}, of course.) +This becomes then a stand-alone executable for \dos, which doesn't need the +\file{GO32.EXE} on the machine where it should run. +\end{enumerate} + +% +% + +% PMODE/DJ +\subsection{PMODE/DJ} +You can also use the PMODE/DJ extender to run your \fpk applications. +To make an executable which works with the PMODE extender, you can simply +create an GO32V2 executable (the default), and then convert it to a PMODE +executable with the following two extra commands: +\begin{enumerate} +\item First, strip the GO32V2 header of the executable: +\begin{verbatim} +EXE2COFF PROG.EXE +\end{verbatim} +(we suppose that \file{PROG.EXE} is the program generated by the compilation +process. +\item Secondly, add the PMODE stub: +\begin{verbatim} +COPY /B PMODSTUB.EXE+PROG PROG.EXE +\end{verbatim} +If the \file{PMODSTUB.EXE} file isn't in your local directory, you need to +supply the whole path to it. +\end{enumerate} + +That's it. No additional steps are needed to create a PMODE extender +executable. + +Be aware, though, that the PMODE extender doesn't support virtual memory, so +if you're short on memory, you may run unto trouble. Also, officially there +is not support for the PMODE/DJ extender. It just happens that the compiler +and some of the programs it generates, run under this extender too. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Reducing the size of your program +\section{Reducing the size of your program} + +When you created your program, it is possible to reduce its size. This +is possible, because the compiler leaves a lot of information in the +program which, strictly speaking, isn't required for the execution of +it. The surplus of information can be removed with a small program +called \file{strip}. It comes with the \var{GO32} development +environment under \dos, and is standard on \linux machines where you can +do development. The usage is simple. Just type +\begin{verbatim} +strip prog +\end{verbatim} +On the command line, and the \file{strip} program will remove all unnecessary +information from your program. This can lead to size reductions of up to +30 \%. + +You can use the \var{-Xs} switch to let the compiler do this stripping +automatically. Under \linux, you can set the \var{-k-s} option, which does +the same. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Problems +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Compiling problems} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% General problems +\section{General problems} +\begin{itemize} +\item \textbf{IO-error -2 at ...} : Under \linux you can get this message at +compiler startup. It means typically that the compiler doesn't find the +error definitions file. You can correct this mistake with the \var{-Fr} +option under \linux. (\seeo{Fr}) +\item \textbf {Error : File not found : xxx} This typically happens when +your unit path isn't set correctly. Remember that the compiler looks for +units only in the current directory, and in the directory where the compiler +itself is. If you want it to look somewhere else too, you must explicitly +tell it to do so using the \var{-Up} option (\seeo{Up}). +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Problems you may encounter under DOS +\section{Problems you may encounter under DOS} +\begin{itemize} +\item \textbf{No space in environment}.\\ +An error message like this can occur, if you call +\verb|SET_PP.BAT| in the \file{AUTOEXEC.BAT}.\\ +To solve this problem, you must extend your environment memory. +To do this, search a line in the \file{CONFIG.SYS} like +\begin{verbatim} +SHELL=C:\DOS\COMMAND.COM +\end{verbatim} +and change it to the following: +\begin{verbatim} +SHELL=C:\DOS\COMMAND.COM /E:1024 +\end{verbatim} +You may just need to specify a higher value, if this parameter is already set. +\item \textbf{ Coprocessor missing}\\ +If the compiler writes +a message that there is no coprocessor, install +the coprocessor emulation. +\item \textbf{Not enough DPMI memory}\\ +If you want to use the compiler with \var{DPMI} you must have at least +7-8 MB free \var{DPMI} memory. +\end{itemize} + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Configuration. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Compiler configuration} +The output of the compiler can be controlled in many ways. This can be done +essentially in two distinct ways: +\begin{itemize} +\item Using command-line options. +\item Using the configuration file: \file{ppc386.cfg}. +\end{itemize} +The compiler first reads the configuration file. Only then the command line +options are checked. This creates the possibility to set some basic options +in the configuration file, and at the same time you can still set some +specific options when compiling some unit or program. First we list the +command line options, and then we explain how to specify the command +line options in the configuration file. When reading this, keep in mind +that the options are case sensitive. While this is customary for \linux, it +isn't under \dos. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Using the command-line options +\section{Using the command-line options} + +The available options are listed by category: + +% +% + +% General options +\subsection{General options} +\begin{description} +\item[-h] if you specify this option, the compiler outputs a list of all options, +and exits after that. +\olabel{h} +\item[-i] This option tells the compiler to print the copyright information. +\olabel{i} +\item[-l] This option tells the compiler to print the \fpk logo on standard +output. It also gives you the \fpk version number. +\olabel{l} +\item[-Lx] Set the language the compiler uses for its messages. +\olabel{L} +\var{x} can be one of the following: +\begin{itemize} +\item \textbf{D} : Use German. +\item \textbf{E} : Use English. +\end{itemize} +\end{description} + +% +% + +% Options for getting feedback +\subsection{Options for getting feedback} +\begin{description} +\item[-qxx] This option tells the compiler to print on stdout some +information on what it is doing. xx can be one of the following: +\olabel{q} +\begin{itemize} +\item \textbf{x is empty} : Be quiet. Don't output anything +\item \textbf{-} : Give some information. +\item \textbf{--} : Give a lot of information. +\end{itemize} +This is an obsolete option, and is kept only for backwards +compatibility. It may disappear in the future.\\ +\item[-vxxx] Be verbose. \var{xxx} is a combination of the following : +\olabel{v} +\begin{itemize} +\item \var{e} : Tells the compiler to show only errors. This option is on by default. +\item \var{i} : Tells the compiler to show some general information. +\item \var{w} : Tells the compiler to issue warnings. +\item \var{n} : Tells the compiler to issue notes. +\item \var{l} : Tells the compiler to show the line numbers as it processes a +file. Numbers are shown per 100. +\item \var{u} : Tells the compiler to print the names of the files it opens. +\item \var{t} : Tells the compiler to print the names of the files it tries +to open. +\item \var{p} : Tells the compiler to print the names of procedures and +functions as it is processing them. +\item \var{c} : Tells the compiler to warn you when it processes a +conditional. +\item \var{m} : Tells the compiler to write which macros are defined. +\item \var{d} : Tells the compiler to write other debugging info. +\end{itemize} +\item[-w] When this option is specified, the compiler issues warning. To +turn off warnings, specify \var{-w-}\\ +This option is obsolete. and is kept only for backwards compatibility. It +may disappear in the future. +\olabel{w} +\end{description} + +% +% + +% Options concerning files and directories +\subsection{Options concerning files and directories} +\begin{description} +\item [-exxx] (\linux only) \file{xxx} specifies the directory where the +compiler can find the executables \file{as} (the assembler) and \file{ld} (the +compiler). +\olabel{e} +\item [-Fexxx] This option tells the compiler to write errors, etc. to +the file in \file{xxx}. +\olabel{Fe} +\item [-Fgxxx] (\linux only) \file{xxx} specifies the path where the compiler +can find the \gnu C library. +\olabel{Fg} +\item [-Frxxx] (\linux only) \file{xxx} specifies the path where the +compiler can find the error-definitions file. +\olabel{Fr} +\item [-Upxxx] \olabel{Up} Tells the compiler to add \file{xxx} to the path where to find +units. \\ +By default, the compiler only searches for units in the current directory +and the directory where the compiler itself resides. This option tells the +compiler also to look in the directory \file{xxx}. +\end{description} + +% Options controlling the kind of output. +\subsection{Options controlling the kind of output.} +for more information on these options, see also \progref +\begin{description} +\item [-a] \olabel{a} Tells the compiler to generate an assembler source file, and to +call an external assembler (\file{as}) to assemble this file. The file will +not be deleted. +\item [-Axxx] \olabel{A}specifies what kind of assembler should be generated . Here +\var{xxx} is one of the following : +\begin{itemize} +\item \textbf{att} : AT\&T assembler. +\item \textbf{o} : A unix .o (object) file. +\item \textbf{obj} : A OMF file for using the NASM assembler. +\item \textbf{nasm} : a coff file using the NASM assembler. +\item \textbf{wasm} : An assembler file for the Microsoft/Borland/Watcom assembler. +\end{itemize} +\item [-Chxxx] \olabel {Ch} Reserves \var{xxx} bytes heap. +\item [-Ci] \olabel{Ci} Generate Input/output checking code. +\item [-Co] \olabel{Co} Generate Integer overflow checking code. +\item [-Cr] \olabel{Cr} Generate Range checking code. +\item [-Csxxx] \olabel{Cs} Set stack size to \var{xxx}. (\ostwo only). +\item [-dxxx] \olabel{d} Define the symbol name \var{xxx}. This can be used +to conditionally compile parts of your code. +\item [-g] \olabel{g} Generate debugging information for debugging with +\file{gdb}. +\item[-On] \olabel{O} optimize the compiler's output; \var{n} can have one +of the following values : +\begin{description} +\item[a] simple optimizations +\item[g] optimize for size +\item[G] optimize for time +\item[x] optimize maximum +\item[2] optimize for Pentium II (tm) +\item[3] optimize for i386 +\item[4] optimize for i486 +\item[5] optimize for Pentium (tm) +\item[6] optimizations for PentiumPro (tm) +\end{description} +The exact effect of these effects can be found in the appendices of the +\progref. +\item [-s] \olabel{s} Tells the compiler not to call the assembler and linker. +You must specify also \var{-a} if you specify this. +\item[-Txxx] \olabel{T}Specifies the target operating system. \var{xxx} can be one of +the following: +\begin{itemize} +\item \textbf{DOS} : \dos and the DJ DELORIE extender. +\item \textbf{OS2} : OS/2 (2.x) (this is still under development). +\item \textbf{LINUX} : \linux. +\item \textbf{WIN32} : Windows 32 bit (this is still under development). +\item \textbf{GO32V2} : \dos and version 2 of the DJ DELORIE extender. +\end{itemize} +\item [-Xx] \olabel{X} executable options. This tells the compiler what +kind of \linux executable should be generated. the parameter \var{x} +can be one of the following: +\begin{itemize} +\item \textbf{e} : (\linux only) Create an \file{ELF} executable (default). +\item \textbf{c} : (\linux only) Link with the C library. You should only use this when +you start to port \fpk to another operating system. +\item \textbf{s} : (\dos only) Strip the symbols from the executable. +\end{itemize} +\end{description} + +% +% + +% Options concerning the sources (language options) +\subsection{Options concerning the sources (language options)} +for more information on these options, see also \progref +\begin{description} +\item [-Rxxx] \olabel{R} Specifies what assembler you use in your \var{asm} assembler code +blocks. Here \var{xxx} is one of the following: +\begin{description} +\item [att\ ] \var{asm} blocks contain AT\&T assembler. +\item [intel] \var{asm} blocks contain Intel assembler. +\item [direct] \var{asm} blocks should be copied as-is in the assembler +file. +\end{description} +\item [-S2] \olabel{Stwo} Switch on Delphi 2 extensions. +\item [-Sann] \olabel{Sa} How severe should the compiler check your code ? +\var{nn} can be one of the following: +\begin{itemize} +\item \var{0} : Only ANSI Pascal expressions allowed. +\item \var{1} : Do not necessarily assign function results to variables. +\item \var{2} : Address operator \var{@} returns a typed pointer. +\item \var{4} : Assignment results are typed. (This allows constructs like +\var{a:=b:=0}. See also ... +\item \var{9} : Allows expressions with no side effect. \remark{Florian ???} +\end{itemize} +\item [-Sc] \olabel{Sc} Support C-style operators, i.e. \var{*=, +=, /= and +-=}. +\item [-Sg] \olabel{Sg} Support the \var{label} and \var{goto} commands. +\item [-Si] \olabel{Si} Support \var{C++} style INLINE. +\item [-Sm] \olabel{Sm} Support C-style macros. +\item [-So] \olabel{So} Try to be Borland TP compatible (no function +overloading etc.). +\item [-Ss] \olabel{Ss} The name of constructors must be \var{init}, and the +name of destructors should be \var{done}. +\item [-St] \olabel{St} Allow the \var{static} keyword in objects. +\item [-Un] \olabel{Un} Do not check the unit name. (Normally, the unit name +is the same as the filename. This option allows both to be different.) +\item [-Us] \olabel{Us} Compile a system unit. This option causes the +compiler to define only some very basic types. +\end{description} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Using the configuration file +\section{Using the configuration file} +\label{se:config_file} +Using the configuration file \file{ppc386.cfg} is an alternative to command +line options. When a configuration file is found, it is read, and the lines +in it are treated like you typed them on the command line. They are treated +before the options that you type on the command line. + +The compiler looks for the \file{ppc386.cfg} file in the following places : +\begin{enumerate} +\item The current directory. +\item Under \dos, the directory where the compiler is. Under \linux, + the compiler looks in the \file{/etc} directory, or, if specified, +the directory in the \var{PPC\_CONFIG\_PATH} environment variable. +\end{enumerate} +When the compiler has finished reading the configuration file, it continues +to treat the command line options. + +One of the command-line options allows you to specify a second configuration +file: Specifying \file{@foo} on the command line will open file \file{foo}, +and read further options from there. When the compiler has finished reading +this file, it continues to process the command line. + +An important feature in the configuration file is that you can specify +sections. They behave much like conditional defines. +Suppose the following configuration file (named \file{myconf}) +\begin{verbatim} +-a +#section first +-Up/some_path +#section second +-Up/other_path. +\end{verbatim} +When you invoke the compiler as follows: +\begin{verbatim} + ppc386 -dfirst @myconf foo.pp +\end{verbatim} +then the compiler will read the part of the configuration file coming before +the line containing \var{\#section second}. As a result the unit search path will be set +to \file{/some\_path}. +If, on the other hand, you invoke the compiler as +\begin{verbatim} + ppc386 -dsecond @myconf foo.pp +\end{verbatim} +Then the configuration file will be read as if the part between +\var{\#section first} and \var{\#section second} didn't exist, resulting +in a unit search path of \file{/other\_path}. +If you put a \var{\#section common} on a line, everything that follows this +keyword will be read, whatever the defined constants. + +In short, the \var{\#define} keywords act as conditionals. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Porting. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Porting Turbo Pascal Code} + +\fpk was designed to resemble Turbo Pascal as closely as possible. There +are, of course, restrictions. Some of these are due to the fact that \fpk is +a 32-bit compiler. Other restrictions result from the fact that \fpk works +on more than one operating system. + +In general we can say that if you keep your program code close to ANSI +Pascal, you will have no problems porting from Turbo Pascal, or even Delphi, to +\fpk. To a large extent, the constructs defined by Turbo Pascal are +supported. + +In the following sections we will list the Turbo Pascal constructs which are +not supported in \fpk, and we will list in what ways \fpk extends the Turbo +Pascal language. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Things that will not work +\section{Things that will not work} +Here we give a list of things which are defined/allowed in Turbo Pascal, but +which are not supported by \fpk. Where possible, we indicate the reason. +\begin{enumerate} +\item Parameter lists of previously defined functions and procedures must +match exactly. The reason for this is the function overloading mechanism of +\fpk. (however, \seeo{So}) +\item \var {(* ... *)} as comment delimiters are not allowed in versions +older than 0.9.1. This can easily be remedied with a grown-up editor. +\item The \var{MEM, MEMW, MEML} and \var{PORT} variables for memory and port +access are not available. This is due to the operating system. Under +\dos, the extender unit (\file {GO32.PPU} provides functions to remedy this. +\item \var{PROTECTED, PUBLIC, TRY, THROW, EXCEPTION} are reserved words. +This means you cannot create procedures or variables with the same name. +While they are not reserved words in Turbo Pascal, they are in Delphi. +\item The reserved words \var{FAR, NEAR} are ignored. This is +because \fpk is a 32 bit compiler, so they're obsolete. +\item \var{INTERRUPT} only will work on a DOS machine. +\item Boolean expressions are only evaluated until their result is completely +determined. The rest of the expression will be ignored. +\item At the moment of writing, the assembler syntax used in \fpk is \var{AT\&T} +assembler syntax. This is mainly because \fpk uses \gnu \var{as}. +\item Turbo Vision is not available. +\item The 'overlay' unit is not available. It also isn't necessary, since +\fpk is a 32 bit compiler, so program size shouldn't be a point. +\item There are more reserved words. (see appendix \ref{ch:reserved} for a +list of all reserved words.) +\item The command-line parameters of the compiler are different. +\item The compiler switches behave different. +\item Units are not binary compatible. +\end{enumerate} + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Things which are extra +\section{Things which are extra} +Here we give a list of things which are possible in \fpk, but which +didn't exist in Turbo Pascal or Delphi. +\begin{enumerate} +\item There are more reserved words. (see appendix \ref{ch:reserved} for a +list of all reserved words.) +\item Functions can also return complex types, such as records and arrays. +\item You can handle function results in the function itself, as a variable. +Example +\begin{verbatim} +function a : longint; + +begin + a:=12; + while a>4 do + begin + {...} + end; +end; +\end{verbatim} +The example above would work with TP, but the compiler would assume +that the \var{a>4} is a recursive call. To do a recursive call in +this you must append \var{()} behind the function name: +\begin{verbatim} +function a : longint; + +begin + a:=12; + { this is the recursive call } + if a()>4 then + begin + {...} + end; +end; +\end{verbatim} +\item There is partial support of Delphi constructs. (see the \progref for +more information on this). +\item The \var{exit} call accepts a return value for functions. +\begin{verbatim} +function a : longint; + +begin + a:=12; + if a>4 then + begin + exit(a*67); {function result upon exit is a*67 } + end; +end; +\end{verbatim} +\item \fpk supports function overloading. That is, you can define many +functions with the same name, but with different arguments. For example: +\begin{verbatim} +procedure DoSomething (a : longint); +begin +{...} +end; + +procedure DoSomething (a : real); +begin +{...} +end; +\end{verbatim} +You can then call procedure \var{DoSomething} with an argument of type +\var{Longint} or \var{Real}.\\ +This feature has the consequence that a previously declared function must +always be defined with the header completely the same: +\begin{verbatim} +procedure x (v : longint); forward; + +{...} + +procedure x;{ This will overload the previously declared x} +begin +{...} +end; +\end{verbatim} +This construction will generate a compiler error, because the compiler +didn't find a definition of \var{procedure x (v : longint);}. Instead you +should define your procedure x as: +\begin{verbatim} +procedure x (v : longint); +{ This correctly defines the previously declared x} +begin +{...} +end; +\end{verbatim} +\end{enumerate} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Turbo Pascal compatibility mode +\section{Turbo Pascal compatibility mode} +When you compile a program with the \var{-So} switch, the compiler will +attempt to mimic the Turbo Pascal compiler in the following ways: +\begin{itemize} +\item Assigning a procedural variable doesn't require a @ operator. One of +the differences between Turbo Pascal and \fpk is that the latter requires +you to specify an address operator when assigning a value to a procedural +variable. In Turbo Pascal compatibility mode, this is not required. +\item Procedure overloading is disabled. +\item Forward defined procedures don't need the full parameter list when +they are defined. Due to the procedure overloading feature of \fpk, you must +always specify the parameter list of a function when you define it, even +when it was declared earlier with \var{Forward}. In Turbo Pascal +compatibility mode, there is no function overloading, hence you can omit the +parameter list: +\begin{verbatim} +Procedure a (L : Longint); Forward; + +... + +Procedure a ; { No need to repeat the (L : Longint) } + +begin + ... +end; + +\end{verbatim} +\item recursive function calls are handled dfferently. Consider the +following example : +\begin{verbatim} +Function expr : Longint; + +begin + ... + Expr:=L: + Writeln (Expr); + ... +end; +\end{verbatim} +In Turbo Pascal compatibility mode, the function will be called recursively +when the \var{writeln} statement is processed. In \fpk, the function result +will be printed. In order to call the function recusively under \fpk, you +need to implement it as follows : +\begin{verbatim} +Function expr : Longint; + +begin + ... + Expr:=L: + Writeln (Expr()); + ... +end; +\end{verbatim} +\item Any text after the final \var{End.} statement is ignored. Normally, +this text is processed too. +\item You cannot assign procedural variables to void pointers. +\item The @ operator is typed when applied on procedures. +\item You cannot nest comments. +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Utilities. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Utilities and units that come with Free Pascal} +Besides the compiler and the Run-Time Library, \fpk comes with some utility +programs and units. Here we list these programs and units. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Supplied programs +\section{Supplied programs} + +\begin{itemize} +\item \file{dumppu} is a program which shows the contents of a \fpk unit. It +comes in source form, and must be compiled before you can use it. Once +compiled, you can just issue the following command +\begin{verbatim} + dumppu foo.ppu +\end{verbatim} +to display the contents of the \file{foo.ppu} unit. +\item Also distributed with Free Pascal comes a series of demonstration programs. +These programs have no other purpose than demonstrating the capabilities of +\fpk. They are located in the \file{demo} directory of the sources. +\item All example programs of the documentation are available. Check out the +directories that end on \file{ex} in the documentation sources. There you +wll find all example sources. +\end{itemize} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Supplied units +\section{Supplied units} +Here we list the units that come with the \fpk distribution. Since there is +a difference in the supplied units per operating system, we list them +separately per system. + +% +% + +% Under DOS +\subsection{Under DOS} +\begin{itemize} +\item \seestrings\ This unit provides basic +string handling routines for the \var{pchar} type, comparable to similar +routines in standard \var{C} libraries. +\item \seeobjects\ This unit provides basic +routines for handling objects. +\item \seedos\ This unit provides basic routines for +accessing the operating system \dos. It provides almost the same +functionality as the Turbo Pascal unit. +\item \seeprinter\ This unit provides all you +need for rudimentary access to the printer. +\item \seegetopts\ This unit gives you the +\gnu \var{getopts} command-line arguments handling mechanism. +It also supports long options. +\item \seecrt\ This unit provides basic screen +handling routines. It provides the same functionality as the Turbo Pascal \var{CRT} +unit. +\item \seegraph\ This unit provides basic graphics +handling, with routines to draw lines on the screen, display texts etc. It +provides the same functions as the Turbo Pascal unit. +\item \seego\ This unit provides access to possibilities of the \var{GO32} +\dos extender. +\end{itemize} +\remark{Florian, I don't know the full list - let me know what is available} + +% +% + +% Under Linux +\subsection{Under Linux} +\begin{itemize} +\item \seestrings\ This unit provides basic +string handling routines for the \var{PChar} type, comparable to similar +routines in standard \var{C} libraries. +\item \seeobjects\ This unit provides basic +routines for handling objects. +\item \seecrt\ This unit provides basic screen +handling routines. It provides the same functionality Turbo Pascal \var{CRT} +unit. It works on any terminal which supports the \var{vt100} escape +sequences. +\item \seedos\ This unit provides an emulation of the +same unit under \dos. It is intended primarily for easy porting of Pascal +programs from \dos to \linux. For good performance, however, it is +recommended to use the \var{linux} unit. +\item \seelinux This unit provides access to the +\linux operating system. It provides most file and I/O handling routines +that you may need. It implements most of the standard \var{C} library constructs +that you will find on a Unix system. If you do a lot of disk/file +operations, the use of this unit is recommended over the one you use under +Dos. +\item \seeprinter\ This unit provides an +interface to the standard Unix printing mechanism. +\item \seegetopts This unit gives you the +\gnu \var{getopts} command-line arguments handling mechanism. +It also supports long options. +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Debugging +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Debugging your Programs} + +\fpk supports debug information for the \gnu debugger \var{gdb}. +This chapter describes shortly how to use this feature. It doesn't attempt +to describe completely the \gnu debugger, however. +For more information on the workings of the \gnu debugger, see the \var{gdb} +users' guide. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Compiling your program with debugger support +\section{Compiling your program with debugger support} +First of all, you must be sure that the compiler is compiled with debugging +support. Unfortunately, there is no way to check this at run time, except by +trying to compile a program with debugging support. + +To compile a program with debugging support, just specify the \var{-g} +option on the command-line, as follows: +\begin{verbatim} +ppc386 -g hello.pp +\end{verbatim} +This will generate debugging information in the executable from your +program. You will notice that the size of the executable increases +substantially because of this\footnote{A good reason not to include debug +information in an executable you plan to distribute.}. + +Note that the above will only generate debug information {\var for the code +that has been generated} when compiling \file{hello.pp}. This means that if +you used some units (the system unit, for instance) which were not compiled +with debugging support, no debugging support will be available for the code +in these units. + +There are 2 solutions for this problem. +\begin{enumerate} +\item Recompile all units manually with the \var{-g} option. +\item Specify the 'build' option (\var{-B}) when compiling with debugging +support. This will recompile all units, and insert debugging information in +each of the units. +\end{enumerate} +The second option may have undesirable side effects. It may be that some +units aren't found, or compile incorrectly due to missing conditionals, +etc.. + +If all went well, the executable now contains the necessary information with +which you can debug it using \gnu \var{gdb}. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Using \var{gdb +\section{Using \var{gdb} to debug your program} + +To use gdb to debug your program, you can start the debugger, and give it as +an option the name of your program: +\begin{verbatim} +gdb hello +\end{verbatim} +This starts the debugger, and the debugger immediately loads your program +into memory, but it does not run the program yet. Instead, you are presented +with the following (more or less) message, followed by the \var{gdb} prompt +\var{'(gdb)'}: +\begin{verbatim} +GDB is free software and you are welcome to distribute copies of it + under certain conditions; type "show copying" to see the conditions. +There is absolutely no warranty for GDB; type "show warranty" for details. +GDB 4.15.1 (i486-slackware-linux), +Copyright 1995 Free Software Foundation, Inc... +(gdb) +\end{verbatim} +To start the program you can use the \var{run} command. You can optionally +specify command-line parameters, which will then be fed to your program, for +example: +\begin{verbatim} +(gdb) run -option -anotheroption needed_argument +\end{verbatim} +If your program runs without problems, \var{gdb} will inform you of this, +and return the exit code of your program. If the exit code was zero, then +the message \var{'Program exited normally'}. + +If something went wrong (a segmentation fault or so), \var{gdb} will stop +the execution of your program, and inform you of this with an appropriate +message. You can then use the other \var{gdb} commands to see what happened. +Alternatively, you can instruct \var{gdb} to stop at a certain point in your +program, with the \var{break} command. + +Here is a short list of \var{gdb} commands, which you are likely to need when +debugging your program: +\begin{description} +\item [quit\ ] Exits the debugger. +\item [kill\ ] Stops a running program. +\item [help\ ] Gives help on all \var{gdb} commands. +\item [file\ ] Loads a new program into the debugger. +\item [directory\ ] Add a new directory to the search path for source +files.\\ +{\em Remark:} My copy of gdb needs '.' to be added explicitly to the search +path, otherwise it doesn't find the sources. +\item [list\ ] Lists the program sources per 10 lines. As an option you can +specify a line number or function name. +\item [break\ ] Sets a breakpoint at a specified line or function +\item [awatch\ ] Sets a watch-point for an expression. A watch-point stops +execution of your program whenever the value of an expression is either +read or written. +\end{description} + +for more information, see the \var{gdb} users' guide, or use the \var{'help'} +function in \var{gdb}. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% CGI. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{CGI programming in Free Pascal} +In these days of heavy WWW traffic on the Internet, CGI scripts have become +an important topic in computer programming. While CGI programming can be +done with almost any tool you wish, most languages aren't designed for it. +Perl may be a notable exception, but perl is an interpreted language, the +executable is quite big, and hence puts a big load on the server machine. + +Because of its simple, almost intuitive, string handling and its easy syntax, +Pascal is very well suited for CGI programming. Pascal allows you to quickly +produce some results, while giving you all the tools you need for more +complex programming. The basic RTL routines in principle are enough to get +the job done, but you can create, with relatively little effort, some units +which can be used as a base for more complex CGI programming. + +That's why, in this chapter, we will discuss the basics of CGI in \fpk. +In the subsequent, we will assume that the server for which the programs are +created, are based upon the NCSA \var{httpd} WWW server, as the examples +will be based upon the NCSA method of CGI programming\footnote{... and it's +the only WWW-server I have to my disposition at the moment.}. + +The two example programs in this chapter have been tested on the command line +and worked, under the condition that no spaces were present in the name and +value pairs provided to them. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Getting your data +\section{Getting your data} +Your CGI program must react on data the user has filled in on the form which +your web-server gave him. The Web server takes the response on the form, and +feeds it to the CGI script. + +There are essentially two ways of feeding the data to the CGI script. We will +discuss both. + +% +% + +% Data coming through standard input. +\subsection{Data coming through standard input.} +The first method of getting your data is through standard input. This method +is invoked when the form uses a form submission method of \var{POST}. +The web browser sets three environment variables \var{REQUEST\_METHOD}, +\var{CONTENT\_TYPE} and \var{CONTENT\_LENGTH}. It feeds then the results of +the different fields through standard input to the CGI script. +All the Pascal program has to do is : +\begin{itemize} +\item Check the value of the \var{REQUEST\_METHOD} environment variable. The +\var{getenv} function will retrieve this value this for you. +\item Check the value of the \var{CONTENT\_TYPE} environment variable. +\item Read \var{CONTENT\_LENGTH} characters from standard input. \var{read +(c)} with \var{c} of type \var{char} will take care of that. +\end{itemize} +if you know that the request method will always be \var{POST}, and the +\var{CONTENT\_TYPE} will be correct, then you can skip the first two steps. +The third step can be done easier: read characters until you reach the +end-of-file marker of standard input. + +The following example shows how this can be achieved: +\begin{verbatim} +program cgi_post; + +uses dos; + +const max_data = 1000; + +type datarec = record + name,value : string; + end; + +var data : array[1..max_data] of datarec; + i,nrdata : longint; + c : char; + literal,aname : boolean; + +begin +writeln ('Content-type: text/html'); +writeln; +if getenv('REQUEST_METHOD')<>'POST' then + begin + writeln ('This script should be referenced with a METHOD of POST'); + write ('If you don''t understand this, see this '); + write ('< A HREF="http://www.ncsa.uiuc.edu/SDG/Softare/Mosaic'); + writeln ('/Docs/fill-out-forms/overview.html">forms overview.'); + halt(1); + end; +if getenv('CONTENT_TYPE')<>'application/x-www-form-urlencoded' then + begin + writeln ('This script can only be used to decode form results'); + halt(1) + end; +nrdata:=1; +aname:=true; +while not eof(input) do + begin + literal:=false; + read(c); + if c='\' then + begin + literal:=true; + read(c); + end; + if literal or ((c<>'=') and (c<>'&')) then + with data[nrdata] do + if aname then name:=name+c else value:=value+c + else + begin + if c='&' then + begin + inc (nrdata); + aname:=true; + end + else + aname:=false; + end + end; +writeln ('

Form Results :

'); +writeln ('You submitted the following name/value pairs :'); +writeln ('
    '); +for i:=1 to nrdata do writeln ('
  • ',data[i].name,' = ',data[i].value); +writeln ('
'); +end. +\end{verbatim} +While this program isn't shorter than the C program provided as an example +at NCSA, it doesn't need any other units. everythig is done using standard +Pascal procedures\footnote{actually, this program will give faulty results, +since spaces in the input are converted to plus signs by the web browser. +The program doesn't check for this, but that is easy to change. +The main concern here is to give the working principle.}. + +Note that this program has a limitation: the length of names and values is +limited to 255 characters. This is due to the fact that strings in Pascal +have a maximal length of 255. It is of course easy to redefine the +\var{datarec} record in such a way that longer values are allowed. +In case you have to read the contents of a \var{TEXTAREA} form element, +this may be needed. + + +% Data passed through an environment variable +\subsection{Data passed through an environment variable} +If your form uses the \var{GET} method of passing it's data, the CGI script +needs to read the \var{QUERY\_STRING} environment variable to get it's data. +Since this variable can, and probably will, be more than 255 characters long, +you will not be able to use normal string methods, present in pascal. \fpk +implements the \var{pchar} type, which is a pointer to a null-terminated +array of characters. +And, fortunately, \fpk has a +\seestrings\ unit, which eases the use of the +\var{pchar} type. + + +The following example illustrates what to do in case of a method of \var{GET} +\begin{verbatim} +program cgi_get; + +uses strings,linux; + +const max_data = 1000; + +type datarec = record + name,value : string; + end; + +var data : array[1..max_data] of datarec; + i,nrdata : longint; + p : PChar; + literal,aname : boolean; + +begin +Writeln ('Content-type: text/html'); +Writeln; +if StrComp(GetEnv('REQUEST_METHOD'),'POST')<>0 then + begin + Writeln ('This script should be referenced with a METHOD of GET'); + write ('If you don''t understand this, see this '); + write ('< A HREF="http://www.ncsa.uiuc.edu/SDG/Softare/Mosaic'); + Writeln ('/Docs/fill-out-forms/overview.html">forms overview.'); + halt(1); + end; +p:=GetEnv('QUERY_STRING'); +nrdata:=1; +aname:=true; +while p^<>#0 do + begin + literal:=false; + if p^='\' then + begin + literal:=true; + inc(longint(p)); + end; + if ((p^<>'=') and (p^<>'&')) or literal then + with data[nrdata] do + if aname then name:=name+p^ else value:=value+p^ + else + begin + if p^='&' then + begin + inc (nrdata); + aname:=true; + end + else + aname:=false; + end; + inc(longint(p)); + end; +Writeln ('

Form Results :

'); +Writeln ('You submitted the following name/value pairs :'); +Writeln ('
    '); +for i:=1 to nrdata do writeln ('
  • ',data[i].name,' = ',data[i].value); +Writeln ('
'); +end. +\end{verbatim} +Although it may not be written in the most elegant way, this program does +the same thing as the previous one. It also suffers from the same drawback, +namely the limited length of the \var{value} field of the \var{datarec}. + +This drawback can be remedied by redefining \var{datarec} as follows: +\begin{verbatim} +type datarec = record; + name,value : pchar; + end; +\end{verbatim} +and assigning at run time enough space to keep the contents of the value +field. This can be done with a +\begin{verbatim} + getmem (data[nrdata].value,needed_number_of_bytes); +\end{verbatim} +call. After that you can do a +\begin{verbatim} +strlcopy (data[nrdata].value,p,needed_number_of_bytes); +\end{verbatim} +to copy the data into place. + +You may have noticed the following unorthodox call : +\begin{verbatim} +inc(longint(p)); +\end{verbatim} +\fpk doesn't give you pointer arithmetic as in C. However, \var{longints} and +\var{pointers} have the same length (namely 4 bytes). Doing a type-cast to a +\var{longint} allows you to do arithmetic on the \var{pointer}. + +Note however, that this is a non-portable call. This may work on the I386 +processor, but not on a ALPHA processor (where a pointer is 8 bytes long). +This will be remedied in future releases of \fpk. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Producing output +\section{Producing output} +The previous section concentrated mostly on getting input from the web +server. To send the reply to the server, you don't need to do anything +special.You just print your data on standard output, and the Web-server will +intercept this, and send your output to the WWW-client waiting for it. + +You can print anything you want, the only thing you must take care of is +that you supply a \var{Contents-type} line, followed by an empty line, as +follows: +\begin{verbatim} +Writeln ('Content-type: text/html'); +Writeln; +{ ...start output of the form... } + +\end{verbatim} + +And that's all there is to it ! + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% I'm under Windows, what now ? +\section{I'm under Windows, what now ?} +Under Windows the system of writing CGI scripts is totally different. If you +use \fpk under Windows then you also should be able to do CGI programming, +but the above instructions will not work. + +If some kind soul is willing to write a section on CGI programming under +Windows, I'd be willing to include it here. +\appendix + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% APPENDIX A. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Alphabetical listing of command-line options} +The following is alphabetical listing of all command-line options, as +generated by the compiler: +\begin{verbatim} +PPC386 [options] [options] + + switch option on, - off + with * marked options have no effect + with ! marked options are only partial implemented + -a the compiler doesn't delete the generated assembler file + -B build + -C code generation options + * -Ca + * -Ce + + -Chxxxx xxxx bytes heap + (must be less than 67107840 und greater than 1023 + -Ci IO-checking + -Co check overflow of integer operations + -Cr range checking + -Csxxxx stack size (only OS/2) + + -dxxx defines the symbol xxx + -D controlls the generation of DEF file (only OS/2) + -Ddxxxx xxxx is the description + -Do generate DEF file + -Dw PM application + -exxxx xxxx path to executables (only LINUX) + -g generate debugger informations + -F set file names and pathes + -Fexxxx redirect error output to xxxx + -Fgxxxx xxxxx search path for the GNU C lib (LINUX only) + -Frxxxx xxxxx search path for the error message file (only LINUX) + -L set language + -LD german + -LE english + -l write logo + -i information + -Ixxx adds xxx to include path + -n don't read the default config file + -oxxx change the name of the executable produced to xxx + -q- write information when compiling (obsolete, see -v) + -S syntax options + -S2 switch some Delphi 2 extension on + -Sa semantic check of expressions + a higher level includes the lower + -Sa0 only ANSI pascal expressions are allowed + -Sa1 functions results havn't to be assigned to variables + -Sa2 @-operator returns typed pointer + -Sa4 assigment results are typed (allows a:=b:=0) + -Sa9 allows expressions with no side effect + -Sc supports operators like C (*=,+=,/= and -=) + -Sg allows LABEL and GOTO + -Si support C++ stlyed INLINE + -Sm support macros like C (global) + -So tries to be TP/BP 7.0 compatible + -Ss the name of constructors must be init + the name of destructors must be done + -St allows static keyword in objects + -s don't call assembler and linker (only with -a) + -T target operating system + -TDOS DOS extender by DJ Delorie + -TOS2 OS/2 2.x + -TLINUX Linux + ! -TWin32 Windows 32 Bit + -TGO32V2 version 2 of DJ Delorie DOS extender + -uxxx undefines the symbol xxx + -U unit options + -Un don't check the unit name + -Us compile a system unit + -Upxxxx adds xxxx to the unit path + -vxxx Be verbose. xxx is a combination of the following letters : + e : Show errors (default) i : Show general info + w : Show warnings l : Show linenumbers + u : Show used files t : Show tried files + p : Show compiled procedures c : Show conditionals + d : Show debug info m : Show defined macros + -w- turns warnings off (Obsolete, see -v) + -X executable options + -Xc link with the c library + -Xe create ELF executable + +Processor specific options: + -A output format + -Aatt AT&T assembler + -Ao coff file using GNU AS + -Aobj OMF file using NASM + -Anasm coff file using NASM + -Amasm assembler for the Microsoft/Borland/Watcom assembler + -R assembler reading style + -Ratt read AT&T style assembler + -Rintel read Intel style assembler + -Rdirect copy assembler text directly to assembler file + -O optimizations + -Oa simple optimizations + -Og optimize for size + -OG optimize for time + -Ox optimize maximum + -O2 optimize for Pentium II (tm) + -O3 optimize for i386 + -O4 optimize for i486 + -O5 optimize for Pentium (tm) + -O6 optimizations for PentiumPro (tm) + -h,-? shows this help +\end{verbatim} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% APPENDIX B. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Alphabetical list of reserved words} +\label{ch:reserved} +\latex{\begin{multicols}{3}}% \texttt +\begin{verbatim} +absolute +abstract +and +array +as +asm +assembler +begin +break +case +class +const +constructor +continue +destructor +dispose +div +do +downto +else +end +except +exit +export +exports +external +fail +false +far +file +finally +for +forward +function +goto +if +implementation +in +inherited +initialization +inline +interface +interrupt +is +label +library +mod +name +near +new +nil +not +object +of +on +operator +or +otherwise +packed +private +procedure +program +property +protected +public +raise +record +repeat +self +set +shl +shr +string +then +to +true +try +type +unit +until +uses +var +virtual +while +with +xor +\end{verbatim} +\latex{\end{multicols}} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% APPENDIX C. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Compiler error messages} +\begin{description} +\item [unexpected end of file] +this typically happens in on of the following cases : +\begin{itemize} +\item The source file ends befor then final \var{end.} statement. This +happens mostly when the \var{begin} and \var{end} statements aren't +balanced; +\item An include file ends in the middle of a statement. +\item A comment wasn't closed. +\end{itemize} +\item [duplicate identifier:] +The identifier was already declared in the current scope. +\item [syntax error:] +An error against the Turbo Pascal language was encountered. This happens +typically when an illegal character is found in the sources file. +\item [out of memory] +The compiler doesn't have enough memory to compile your program. There are +several remedies for this: +\begin{itemize} +\item If you're using the build option of the compiler, try compiling the +different units manually. +\item If you're compiling a huge program, split it up in units, and compile +these separately. +\item If the previous two don't work, recompile the compiler with a bigger +heap (you can use the \var{-Ch} option for this, \seeo{Ch}) +\end{itemize} +\item [unknown identifier] +The identifier encountered hasn't been declared, or is used outside the +scope where it's defined. +\item [illegal character] +An illegal character was encountered in the input file. +\item [source too long] +The compiler cannot cope with source files longer than (???) +\item [INLINE not supported (use option -Si for C++ styled inlining)] +You tried to compile a program with C++ style inlining, and forgot to +specify the \var{-Si} option (\seeo{Si}). The compiler doesn't support C++ +styled inlining by default. +\item [NEAR ignored] +This is a warning. \var{NEAR} is a construct for 8 or 16 bit programs. Since +the compile generates 32 bit programs, it ignores this directive. +\item [FAR ignored] +This is a warning. \var{FAR} is a construct for 8 or 16 bit programs. Since +the compile generates 32 bit programs, it ignores this directive. +\item [INTERRUPT ignored] +Interrupt procedures aren't possible on operating systems, other than DOS, +it isn't allowed to take over an interrupt at the user level. (versions +older than 0.9.2 didn't have \var{INTERRUPT} support. +\item [private methods can't be VIRTUAL] +You declared a method in the private part of a object (class) as +\var{virtual}. This is not allowed. Private methods cannot be overridden +anyway. +\item [constructor can't be private or protected] +Constructors must be in the 'public' part of an object (class) declaration. +\item [destructor can't be private or protected] +Destructors must be in the 'public' part of an object (class) declaration. +\item [identifier not found] +\item [local class definitions are not allowed] +Classes must be defined globally. +\item [anonym class definitions are not allowed] +\item [type identifier expected] +The identifier is not a type, or you forgot to supply a type identifier. +\item [identifier already as type identifier declared] +You are trying to redefine a type. +\item [type identifier not defined] +The compiler encountered an unknown type. +\item [type mismatch] +This can happen in many cases: +\begin{itemize} +\item The variable you're assigning to is of a different type than the +expression in the assignment. +\item You are calling a function or procedure with parameters that are +incompatible with the parameters in the function or procedure definition. +\end{itemize} +\item [statement expected] + +\item [illegal integer constant] + +\item [illegal expression] +\item [expression too complicated - FPU stack overflow] +Your expression is too long for the compiler. You should try dividing the +construct over multiple assignments. +\item [CONTINUE not possible] +You're trying to use \var{continue} outside a loop construction. +\item [BREAK not possible] +You're trying to use \var{break} outside a loop construction. +\item [exception handling needed to compile this (command line -Se)] +Older (less than 0.6.6) versions of \fpk only. Your statement needs exception handling. +Exception handling isn't supported by default in the compiler. +Use the \var{-Se} option to turn on exception handling.% (\seeo{Se}) +\item [illegal qualifier] +One of the following is appending : +\begin{itemize} +\item You're trying to access a field of a variable that is not a record. +\item You're indexing a variable that is not an array. +\item You're dereferencing a variable that is not a pointer. +\end{itemize} +\item [illegal count variable] The type of a \var{for} loop must be ordinal. + +\item [ordinal type expected] +The expression must be of ordinal type (i.e. maximum a Longint) +\item [high range limit < low range limit] +You are declaring a subrange, and the lower limit is higher than the high +limit of the range. +\item [illegal unit identifier] +The name of the unit doesn't match the file name. +\item [unknown format of unit file] +The unit the compiler is trying to read is corrupted, or generated with a +newer version of the compiler. +\item [error when reading unit] +The unit the compiler is trying to read is corrupted, or generated with a +newer version of the compiler. +\item [circular unit use] +Two units are using each other in the interface part. This is only allowed +in the implementation part. +\item [too many units] +\fpk has a limit of 1024 units in a program. You can change this behavior +by changing the \var{maxunits} constant in the \file{files.pas} file of the +compiler, and recompiling the compiler. +\item [illegal char constant] +\item [overloaded identifier isn't a function identifier] +\item [overloaded functions have the same parameter list] +You're declaring overloaded functions, but with the same parameter list. +Overloaded function must have at least 1 different parameter in their +declaration. +\item [illegal parameter list] +You are calling a function with parameters that are of a different type than +the declared parameters of the function. +\item [can't determine which overloaded function to call] +You're calling overloaded functions with a parameter that doesn't correspond +to any of the declared function parameter lists. e.g. when you have declared +a function with parameters \var{word} and \var{longint}, and then you call +it with a parameter which is of type \var{integer}. +\item [exception handling not used, however needed by function] +This message is no longer used. +\item [forward declaration not solved:] +This can happen in two cases: +\begin{itemize} +\item This happens when you declare a function (in the \var{interface} part, or +with a \var{forward} directive, but do not implement it. +\item You reference a type which isn't declared in the current \var{type} +block. +\end{itemize} +\item [input file not found] +\fpk cannot find the program or unit source file, or the included file isn't +found. +\item [function header doesn't match the forward declaration] +You declared the function in the \var{interface} part, or with the +\var{forward} directive, but define it with a different parameter list. +\item [unknown field identifier] +The field doesn't exist in the record definition. +\item [parameter list size exceeds 65535 bytes] +The I386 processor limits the parameter list to 65535 bytes (the \var{RET} +instruction causes this) +\item [function nesting > 31] +You can nest function definitions only 31 times. +\item [illegal compiler switch] +You included a compiler switch (i.e. \var{\{\$... \}}) which the compiler +doesn't know. +\item [can't open include file] +You want to include (i.e \var{\{\$i file\}}) which the compiler doesn't +find. Check if the filename is correct. +\item [record or class type expected] +The variable or expression isn't of the type \var{record} or \var{class}. +\item [not found:] +An unknown symbol was encountered. +\item [only values can be jumped over in enumeration types] +\fpk allows enumeration constructions as in C. Given the following +declaration two declarations: +\begin{verbatim} +type a = (A_A,A_B,A_E=:6,A_UAS:=200); +type a = (A_A,A_B,A_E=:6,A_UAS:=4); +\end{verbatim} +The second declaration would produce an error. \var{A\_UAS} needs to have a +value higher than \var{A\_E}, i.e. at least 7. +\item [pointer type expected] +The variable or expression isn't of the type \var{pointer}. +\item [unit is compiled for another operating system] +The unit was compiled with a different target than the target for which +you're compiling now. (see the option \var{-T} \seeo{T}). +\item [typed constants of classes are not allowed] +You cannot declare a constant of type class or object. +\item [duplicate case label] +You are specifying the same label 2 times in a \var{case} statement. +\item [range check error while Eva luting constants] +The constants are out of their allowed range. +\item [illegal type conversion] +When doing a type-cast, you must take care that the sizes of the variable and +the destination type are the same. +\item [class type expected] +The variable of expression isn't of the type \var{class}. +\item [functions variables of overloaded functions are not allowed] +You are trying to assign an overloaded function to a procedural variable. +This isn't allowed. +\item [can't open assembler output file] +The assembler output file cannot be opened. This can have many causes, but +'disk full' is a reasonable guess. +\item [string length must be a value from 1 to 255] +The length of a string in Pascal is limited to 255 characters. You are +trying to declare a string with length greater than 255. +\item [class identifier expected] +The variable isn't of type \var{class}. +\item [method identifier expected] +This identifier is not a method. +\item [function header doesn't match any method of this class] +You are defining a function as a class method, but no such function was +declared in the class. +\item [use extended syntax of DISPOSE and NEW to generate instances of classes] +If you have a pointer \var{a} to a class type, then the statement +\var{new(a)} will not initialize the class (i.e. the constructor isn't +called), although space will be allocated. you should issue the +\var{new(a,init)} statement. This will allocate space, and call the +constructor of the class. +\item [file types must be var parameters] +You cannot specify files as value parameters, i.e. they must always be +declared \var{var} parameters. +\item [string constant exceeds line end] +You forgot probably to include the closing ' in a string. +\item [illegal version of the unit:] +This unit was compiled with an earlier version of \fpk. +\item [illegal floating point constant] +\item [destructors can't have parameters] +You are declaring a destructor with a parameter list. Destructor methods +cannot have parameters. +\item [FAIL can be used in constructors only] +You are using the \var{FAIl} instruction outside a constructor method. +\item [records fields can be aligned to 1,2 or 4 bytes only] +You are specifying the \var{\{\$PACKRECORDS n\} } with an illegal value for +\var{n}. Only 1,2 or 4 are valid in this case. +\item [too many \$ENDIFs or \$ELSEs] +Your \var{\{\$IFDEF ..\}} and {\{\$ENDIF\}} statements aren't balanced. +\item [\$ENDIF expected] +Your \var{\{\$IFDEF ..\}} and {\{\$ENDIF\}} statements aren't balanced. +\item [illegal call by reference parameters] +\item [can't generate DEF file] +\ostwo only. The DEF file cannot be generated. +\item [all overloaded methods must be virtual if one is virtual:] +If you declare overloaded methods in a class, then they should either all be +virtual, or none. You cannot mix them. +\item [overloaded methods which are virtual must have the same return type:] +If you declare virtual overloaded methods in a class definition, they must +have the same return type. +\item [all overloaded virtual methods must support exceptions if one support exceptions:] +If you declare overloaded virtual methods in a class, then they should either +all support exceptions, or none. You cannot mix them. +\item [EXPORT declared functions can't be called] +You are trying to call a procedure you declared as \var{export}. Due to the +different calling scheme of \fpk and C, you cannot call such a function from +within your Pascal program. +\item [EXPORT declared functions can't be nested] +You cannot declare a function or procedure within a function or procedure +that was declared as an export procedure. +\item [methods can't be EXPORTed] +You cannot declare a procedure that is a method for an object as +\var{export}ed. That is, you methods cannot be called from a C program. +\item [SELF is allowed in methods only] +You are trying to use the \var{self} parameter outside an object's method. +Only methods get passed the \var{self} parameters. +\item [call by var parameters have to match exactly] +When calling a function declared with \var{var} parameters, the variables in +the function call must be of exactly the same type. There is no automatic +type conversion. +\item [type identifiers are not allowed in this context] +\item [class identifier expected] +The variable isn't of type \var{class}. +\item [class isn't a super class of the current class] +When calling inherited methods, you are trying to call a method of a strange +class. You can only call an inherited method of a parent class. +\item [methods can be only in other methods called direct with type identifier of the class] +A construction like \var{sometype.somemethod} is only allowed in a method. +\item [illegal INHERITED: class has no super class] +You specified an \var{INHERITED} keyword in a method of a class which has no +parent class, i.e. which isn't derived from another class. +\item [illegal type: pointer to class expected] +You specified an illegal type. +\item [possible illegal call of constructor or destructor (doesn't match to this context)] +\item [class should have one destructor only] +You can declare only one destructor for a class. +\item [expression must be constructor call] +When using the extended syntax of \var{new}, you must specify the constructor +method of the class you are trying to create. The procedure you specified +is not a constructor. +\item [identifier idents no member] +When using the extended syntax of \var{new}, you must specify the constructor +method of the class you are trying to create. The procedure you specified +does not exist. +\item [expression must be destructor call] +When using the extended syntax of \var{dispose}, you must specify the +destructor method of the class you are trying to dispose of. +The procedure you specified is not a destructor. + +\item [assembler: illegal constant] +\item [illegal type declaration of set elements] +\item [illegal expression in set constructor] +\item [type conflict between set elements] +You are specifying elements of a different type for a set. +\item [illegal use of ':'] +\item [expression type must be class or record type] +The expression isn't of type class or record. +\item [the operator / isn't defined for integer, the result will be real, use DIV instead] +When using the '/' operator in \fpk the result will be of type real, when +used with integers. +\item [can't write PPU file] +There is a problem when writing to the unit file. +\item [illegal order of record elements] +When declaring a constant record, you specified the fields in the wrong +order. +\item [the name of constructors must be INIT] +You are declaring a constructor with a name which isn't \var{init}, and the +\var{-Ss} switch is in effect. See the \var{-Ss} switch (\seeo{Ss}). +\item [the name of constructors must be DONE] +You are declaring a constructor with a name which isn't \var{done}, and the +\var{-Ss} switch is in effect. See the \var{-Ss} switch (\seeo{Ss}). +\item [set element type mismatch] +The type of the element doesn't equal the set type. +\item [illegal label declaration] +\item [label not found] +A \var{goto label} was encountered, but the label isn't declared. +\item [GOTO and LABEL are not supported (use command line switch -Sg)] +You must compile a program which has \var{label}s and \var{goto} statements +with the \var{-Sg} switch. By default, \var{label} and \var{goto} aren't +supported. +\item [set expected] +The variable or expression isn't of type \var{set}. +\item [identifier isn't a label] +The identifier specified after the \var{goto} isn't of type label. +\item [label already defined] +You're attempting to define a label two times. (i.e. you put the same label +on two different places.) +\item [label isn't defined:] +A label was declared, but not defined. +\item [constructors and destructors must be methods] +You're declaring a procedure as destructor or constructor, when the +procedure isn't a class method. +\item [error when assembling] +An error occurred when assembling. This can have many causes. +\item [identifier not used:] +This is a warning. The identifier was declared (locally or globally) but +wasn't used (locally or globally). +\item [functions with void return value can't return any value] +In \fpk, you can specify a return value for a function when using +the \var{exit} statement. This error occurs when you try to do this with a +procedure. Procedures cannot return a value. +\item [Hmmm..., this code can't be much efficient] +You construction seems dubious to the compiler. +\item [unreachable code] +You specified a loop which will never be executed. Example: +\begin{verbatim} +while false do + begin + {.. code ...} + end; +\end{verbatim} +\item [This overloaded function can't be local (must be exported)] +You are defining a overloaded function in the implementation part of a unit, +but there is no corresponding declaration in the interface part of the unit. +\item [It's not possible to overload this operator] +You are trying to overload an operator which cannot be overloaded. +\item [Abstract methods can't be called direct] +\fpk understands the \var{abstract} keyword. +\item [the mix of CLASSES and OBJECTS are not allowed] +You cannot use \var{object} and \var{class} intertwined. +\item [macro buffer overflow while reading or expanding a macro] +Your macro or it's result was too long for the compiler. +\item [keyword redefined as macro has no effect] +You cannot redefine keywords with macros. +\item [extension of macros exceeds a deep of 16,\\ perhaps there is a recursive macro definition (crashes the compiler)] +When expanding a macro macros have been nested to a level of 16. +\item [ENDIF without IF(N)DEF] +Your code contains more \var{\{\$ENDIF\}} than \var{\{\$IF(N)DEF\}} +statements. +\item [user defined:] +A user defined warning occurred. see also the \progref +\item [linker: Duplicate symbol:] +Two global symbols in the code have the same name. +\item [linker: Error while reading object file] +The linker couldn't read the object file (the assembled file). +\item [linker: object file not found] +The linker didn't find the object file (the assembled file). +\item [linker: illegal magic number in file:] +The linker cannot determine the type of a file it wants to link in. The type +of a link file is specified using a magic number, which is some pre-defined +constant, unique for each system. +\item [The extended syntax of new or dispose isn't allowed for a class] +You cannot generate an instance of a class with the extended syntax of +\var{new}. The constructor must be used for that. For the same reason, you +cannot call \var{Dispose} to de-allocate an instance of a class, the +destructor must be used for that. +\item [To generate an instance of a class or an object with an abstract method isn't allowed] +You are trying to generate an instance of a class which has an abstract +method that wasn't overridden. +\item [Only virtual methods can be abstract] +You are declaring a method as abstract, when it isn't declared to be +virtual. +\item [Abstract methods shouldn't have any definition (with function body)] +Abstract methods can only be declared, you cannot implement them. They +should be overridden by a descendant class. +\item [can't call the assembler] +An error occurred when calling the assembler. +\item [can't call o2obj] +An error occurred when calling the \var{o} to \var{obj} conversion program. +\item [asm syntax error] +There is an error in the assembly language. +\item [register name expected] +There is an error in the assembly language. The assembler expected a +register and got something else. +\item [asm size mismatch] +There is an error in the assembly language. The sizes of operands and +registers don't match. +\item [no instr match,] +There is an error in the assembly language. An unknown instruction was +encountered. +\item [can't compile unit:] +When trying to do a build, the compiler cannot compile one of the units. +\item [Re-raise isn't possible there] +You are trying to raise an exception where it isn't allowed. You can only +raise exceptions in an \var{except} block. +\end{description} + +\chapter{Run time errors} +The \fpk Run-tim library generates the following errors at run-time +\footnote{The \linux port will generate only a subset of these.}: + +\begin{description} +\item [1 Invalid function number] +You tried to call a \dos function which doesn't exist. +\item [2 File not found] +You can get this error when you tried to do an operation on a file which +doesn't exist. +\item [3 Path not found] +You can get this error when you tried to do an operation on a file which +doesn't exist, or when you try to change to, or remove a directory that doesn't exist, +or try to make a subdirectory of a subdirectory that doesn't exist. +\item [4 Too many open files] +When attempting to open a file for reading or writing, you can get this +error when your program has too many open files. +\item [5 File access denied] +You don't have access to the specified file. +\item [6 Invalid file handle] +If this happens, the file variable you are using is trashed; it +indicates that your memory is corrupted. +\item [12 Invalid file access code] +This will happen if you do a reset or rewrite of a file when \var{FileMode} +is invalid. +\item [15 Invalid drive number] +The number given to the Getdir function specifies a non-existent disk. +\item [16 Cannot remove current directory] +You get this if you try to remove the current diirectory. +\item [17 Cannot rename across drives] +You cannot rename a file such that it would end up on another disk or +partition. +\item [100 Disk read error] +\dos only. An error occurred when reading from disk. Typically when you try +to read past the end of a file. +\item [101 Disk write error] +\dos only. Reported when the disk is full, and you're trying to write to it. +\item [102 File not assigned] +This is reported by Reset, Rewrite, Append, Rename and Erase, if you call +them with an unassigne function as a parameter. +\item [103 File not open] +Reported by the following functions : Close , Read, Write, Seek, +EOf, FilePos, FileSize, Flush, BlockRead, and BlockWrite if the file isn't +open. +\item [104 File not open for input] +Reported by Read, BlockRead, Eof, Eoln, SeekEof or SeekEoln if the file +isn't opened with Reset. +\item [105 File not open for output] +Reported by write if a text file isn't opened with Rewrite. +\item [106 Invalid numeric format] +Reported when a non-numerice value is read from a text file, when a numeric +value was expected. +\item [150 Disk is write-protected] +(Critical error, \dos only.) +\item [151 Bad drive request struct length] +(Critical error, \dos only.) +\item [152 Drive not ready] +(Critical error, \dos only.) +\item [154 CRC error in data] +(Critical error, \dos only.) +\item [156 Disk seek error] +(Critical error, \dos only.) +\item [157 Unknown media type] +(Critical error, \dos only.) +\item [158 Sector Not Found] +(Critical error, \dos only.) +\item [159 Printer out of paper] +(Critical error, \dos only.) +\item [160 Device write fault] +(Critical error, \dos only.) +\item [161 Device read fault] +(Critical error, \dos only.) +\item [162 Hardware failure] +(Critical error, \dos only.) +\item [200 Division by zero] +You are dividing a number by zero. +\item [201 Range check error] +If you compiled your program with range checking on, then you can get this +error in the following cases: +\begin{enumerate} +\item An array was accessed with an index outside its declared range. +\item You're trying to assign a value to a variable outside its range (for +instance a enumerated type). +\end{enumerate} +\item [202 Stack overflow error] +The stack has grown beyond itss maximum size. This error can easily occur if +you have recursive functions. +\item [203 Heap overflow error] +The heap has grown beyond its boundaries, ad you are rying to get more +memory. Please note that \fpk provides a growing heap, i.e. the heap will +try to allocate more memory if needed. However, if the heap has reached the +maximum size allowed by the operating system or hardware, then you will get +this error. +\item [204 Invalid pointer operation] +This you will get if you call dispose or Freemem with an invalid pointer +(notably, \var{Nil}) +\item [205 Floating point overflow] +You are trying to use or produce too large real numbers. +\item [206 Floating point underflow] +You are trying to use or produce too small real numbers. +\item [207 Invalid floating point operation] +Can occur if you try to calculate the square root or logarithm of a negative +number. +\item [210 Object not initialized] +When compiled with range checking on, a program will report this error if +you call a virtal method without having initialized the VMT. +\item [211 Call to abstract method] +Your program tried to execute an abstract virtual method. Abstract methods +should be overridden, and the overriding method should be called. +\item [212 Stream registration error] +This occurs when an invalid type is registered in the objects unit. +\item [213 Collection index out of range] +You are trying to access a collection item with an invalid index. +(objects unit) +\item [214 Collection overflow error] +The collection has reached its maximal size, and you are trying to add +another element. (objects unit) +\item [216 General Protection fault] +You are trying to access memory outside your appointed memory. +\end{description} +\end{document} diff --git a/docs/userpdf.tex b/docs/userpdf.tex new file mode 100644 index 0000000000..bbe09b3315 --- /dev/null +++ b/docs/userpdf.tex @@ -0,0 +1,22 @@ +% +% $Id$ +% This file is part of the FPC documentation. +% Copyright (C) 1997, by Michael Van Canneyt +% +% The FPC documentation is free text; you can redistribute it and/or +% modify it under the terms of the GNU Library General Public License as +% published by the Free Software Foundation; either version 2 of the +% License, or (at your option) any later version. +% +% The FPC Documentation is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% Library General Public License for more details. +% +% You should have received a copy of the GNU Library General Public +% License along with the FPC documentation; see the file COPYING.LIB. If not, +% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +\pdfoutput=1\relax +\input{user.tex}